[Vue] toRef: convert reactive to ref in order to destructure reactive object used inside template
import {reactive, computed} from "vue"
export default {
setup() {
const event = reactive({
capacity: 4,
attending: ["Tim", "Bob"],
spacesLeft: computed(() => {
return event.capacity - event.attending.length
})
})
function increaseCapacity() {
event.capacity++
}
return {event, increaseCapacity}
}
}
In template we will do:
<p>Spaces Left: {{ event.spacesLeft }} out of {{ event.capacity }}</p>
<h2>Attending</h2>
<ul>
<li v-for="(name, index) in event.attending" :key="index">
{{ name }}
</li>
</ul>
<button @click="increaseCapacity()">Increase Capacity</button>
I wondered, might there be any way to destructure the event
object, so that in the template I don’t always have to write event.
?
Introducing toRefs
Luckily, there is a way to do this using the toRefs
method. This method converts a reactive object to a plain object, where each property is a Reactive Reference pointing to the property on the original object. Here is our completed code using this method:
import { reactive, computed, toRefs } from "vue";
export default {
setup() {
const event = reactive({
capacity: 4,
attending: ["Tim", "Bob", "Joe"],
spacesLeft: computed(() => {
return event.capacity - event.attending.length;
})
});
function increaseCapacity() {
event.capacity++;
}
return { ...toRefs(event), increaseCapacity };
}
};
Notice that I’m importing toRefs
and then using it in my return statement, and then destructuring the object. This works great!
Aside
Before continuing on, I want to mention that if our code didn’t need to also return the increaseCapacity
function in the return value, I could have simply written:
return toRefs(event);
This is because our setup
method expects us to return an object, which is exactly what toRefs
returns as well.