我想对通过循环v-for
遍历任意对象集合创建的模板引用元素数组所做的更改做出反应。我想将此数组传递给组件/可组合项并让其对更改做出反应。
文档提供了一种将这些元素保存到数组的方法:https://vuejs.org/guide/essentials/template-refs.html#refs-inside-v-for
我修改了提供的示例,以查看生成的itemsRef
数组是否具有响应性。代码如下:
<script setup>
import { ref, useTemplateRef, watch, markRaw } from 'vue'
const list = ref([1, 2, 3])
const itemRefs = useTemplateRef('items')
watch(itemRefs, () => {
console.log("itemsRef:", itemRefs.value.length);
}, {deep: true});
watch(list, () => {
console.log("list:", list.value.length, itemRefs.value.length);
}, { deep: true });
</script>
<template>
<button @click="list.push(list.length + 1)">add</button>
<ul>
<li v-for="item in list" ref="items">
{{ item }}
</li>
</ul>
</template>
但从其 TypeScript 签名来看,的返回值useTemplateRef
似乎是:ShallowRef
function useTemplateRef<T>(key: string): Readonly<ShallowRef<T | null>>
因此watch
实际上itemRefs
只运行一次:
如您所见,数组的内容正在发生变化(已更新),但vue 未捕获到list
这些变化。我尝试进行深度处理,但没有帮助。itemRefs
watch
有没有办法让 ref 不那么浅?或者还有其他方法?
const { createApp, ref, useTemplateRef, watch, markRaw } = Vue;
const app = createApp({
setup() {
const list = ref([1, 2, 3]);
const itemRefs = useTemplateRef('items');
watch(itemRefs, () => {
console.log("itemsRef: ", itemRefs.value.length);
}, { deep: true });
watch(list, () => {
console.log("list: ", list.value.length, itemRefs.value.length);
}, { deep: true });
return { list }
}
});
app.mount('#app');
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="app">
<button @click="list.push(list.length + 1)">add</button>
<ul>
<li v-for="item in list" ref="items">
{{ item }}
</li>
</ul>
</div>