When use Composition setup and not deconstruct useXX return object, the computeRef need .value at template
Vue version
3.2.21
Link to minimal reproduction
https://stackblitz.com/edit/vitejs-vite-oanufe?file=src/App.vue
Steps to reproduce
create ./test.ts
import { shallowReactive, computed } from "vue";
export const useTest = () => {
const list = [
{ id: 1, name: "1" },
{ id: 2, name: "2" },
];
const disables = shallowReactive(new Set([1]));
return {
okList: computed(() => {
return list.filter((e) => !disables.has(e.id));
}),
};
};
use it with two way at App.vue
<script setup>
import { useTest } from './test';
const test = useTest();
const { okList } = useTest();
</script>
<template>
<div v-for="el in test.okList">
{{ el.name }} -- not ok line
</div>
<div v-for="el in test.okList.value">
{{ el.name }}
</div>
<div class="deconstructed" v-for="el in okList">
{{ el.name }}
</div>
</template>
What is expected?
expect can use test.okList directly at template without .value
<div v-for="el in test.okList">
{{ el.name }} --should work
</div>
What is actually happening?
need .value to read the value as following, really wierd:
<div v-for="el in test.okList.value">
{{ el.name }} --
</div>
System Info
--
Any additional comments?
No response
and looks like when compute is a boolean or number ref, it works as expected, but when it's an array , it broke
I dont see a bug. The composable returns a non-reactive object, whose properties are not unwrapped in the template. While I'm aware this can trip people up, this is documented, expwcted behavior
@LinusBorg
This is because test.okList
is compiled to unref(test).okList
, I feel it should be unref(test.okList)
.
This is explicitly documented behavior so changing it would be a breaking change that would break existing apps all over the place. So it won't happen (until we want to talk about Vue 4 maybe, some day).