I'm trying to toggle references on and off in Vue. This is how I'd like to do it (or something similar) by having a conditional :ref="option.selected? 'foobar': null" on the items:
<script setup lang="ts">
import {ref, useTemplateRef} from "vue";
const options = ref([
{label: "One"},
{label: "Two", selected: true},
{label: "Three"},
]);
const foobar = useTemplateRef('foobar');
</script>
<template>
<span
v-for="option in options"
:key="option.label"
:ref="option.selected? 'foobar': null"
@click="option.selected = !option.selected"
>{{ option.label }}</span>
Selected elements: {{ foobar }}
</template>
But I can only make it work if I wrap the elements in a <template> and use v-if="option.selected" and v-else on the elements:
...
<template>
<template
v-for="option in options"
:key="option.label"
>
<span
v-if="option.selected"
:ref="'foobar'"
@click="option.selected = !option.selected"
>{{ option.label }}</span>
<span
v-else
@click="option.selected = !option.selected"
>{{ option.label }}</span>
</template>
Selected elements: {{ foobar }}
</template>
Clicking the item toggles it being selected.
In the first code block, once an element gets added to refs.foobar, it never gets removed even if it gets deselected. So if I select all the elements, then deselect them all, they all still show in {{ foobar }}. :ref="option.selected? 'foobar': null" does work to conditionally add an element to refs, but it doesn't remove them.
In the second code block, only those elements that are currently selected end up in refs.foobar, however, it's clumsy because I have to repeat exactly the same element with an if-else structure. It needs to refresh a second time to see the correct number of currently selected elements in {{ foobar }}, otherwise it shows the previous number.
My real world use case has a lot more code than just a simple <span> resulting in a lot of duplication. Other than v-if="option.selected" :ref="'foobar'" and v-else the code for the two blocks is identical.
Can values in refs be set conditionally in a simple way that always gives the correct/expected results?