使用ref而非reactive时,如何让数组中单个属性具备响应式?
Vue组件中仅让单个属性响应式实现详情切换功能
我有一个展示数据行的组件,需要实现详情的显示/隐藏切换功能。原本用reactive把数据映射成包含opened属性的数组,功能正常,但不想让整个数组深度响应式。于是尝试用ref只让opened属性响应式,虽然opened具备响应性,但切换功能失效。怎么在不使整个值响应式的前提下让切换功能正常工作?
可正常工作的代码
<script setup> import { defineProps, reactive } from 'vue'; const props = defineProps({ data: { type: Array, required: true, }, dataKey: { type: String, required: true, }, }); const rows = reactive(props.data.map(value => { return { value, opened: false, }; })); function toggleDetails(row) { row.opened = !row.opened; } </script> <template> <div> <template v-for="row in rows" :key="row.value[dataKey]"> <div> <!-- Toggle Details --> <a @click.prevent="() => toggleDetails(row)"> {{ row.value.key }}: {{ row.opened ? 'Hide' : 'Show' }} details </a> <!-- Details --> <div v-if="row.opened" style="border: 1px solid #ccc"> <div>opened: <pre>{{ row.opened }}</pre></div> <div>value: </div> <pre>{{ row.value }}</pre> </div> </div> </template> </div> </template>
尝试的非工作代码
const rows = props.data.map(value => { return { value, opened: ref(false), }; }); function toggleDetails(row) { row.opened.value = !row.opened.value; }
解决方案
问题根源是模板里没正确读取ref的value属性:ref作为顶层属性时会自动解包,但嵌套在普通对象里的ref不会,必须手动访问.value才能获取响应式状态。
修改后的完整代码
<script setup> import { defineProps, ref } from 'vue'; const props = defineProps({ data: { type: Array, required: true, }, dataKey: { type: String, required: true, }, }); const rows = props.data.map(value => { return { value, opened: ref(false), }; }); function toggleDetails(row) { row.opened.value = !row.opened.value; } </script> <template> <div> <template v-for="row in rows" :key="row.value[dataKey]"> <div> <!-- Toggle Details --> <a @click.prevent="() => toggleDetails(row)"> {{ row.value.key }}: {{ row.opened.value ? 'Hide' : 'Show' }} details </a> <!-- Details --> <div v-if="row.opened.value" style="border: 1px solid #ccc"> <div>opened: <pre>{{ row.opened.value }}</pre></div> <div>value: </div> <pre>{{ row.value }}</pre> </div> </div> </template> </div> </template>
关键说明
- 普通对象中的
ref不会自动解包,必须通过.value访问其响应式值 - 这种方式既避免了整个数组被
reactive深度响应式处理,又保证了opened属性的响应性,切换功能就能正常运行
内容的提问来源于stack exchange,提问作者Adriaan Meuris
相关产品推荐
相关产品推荐

