新版写法(Vue3.5以后)
在Vue3.5开始,引入了useTemplateRef(),文档中是这么说的:
当 ref 在 v-for 内部使用时,相应的 ref 应包含一个 Array 值,该值将在 mount 之后填充元素:
<script setup> import { ref, useTemplateRef, onMounted } from 'vue'const list = ref([/* ... */ ])// Declare array for the dynamic collection of refs // CHANGED: The variable name can differ from the value of the Template element's ref attribute. ---> in my example itemRefs custom-name related to ref="items" const itemRefs = useTemplateRef('items')onMounted(() => console.log(itemRefs.value)) </script> <template><ul><li v-for="item in list" ref="items">{{ item }}</li></ul> </template>
来源:v-for内的引用
通过这种方式,您可以动态创建一个 refs 数组。
在过去,可以通过 ref(null) 声明对 Template 元素进行反应式引用。之前有一条严格的规则,声明的 ref 变量的名称必须与 Template 元素的 ref 属性中的字符串匹配。从现在开始,使用 useTemplateRef('ref-attribute-value') ,变量名称不再受此限制。
同样,以前要创建一个动态引用数组,你必须声明一个带有严格变量名的空数组引用。现在,你可以简单地使用 useTemplateRef 配对 v-for 。
使用动态模板 ref-属性值
传递给 useTemplateRef 的值也可以是动态的:
<script setup>
import { useTemplateRef} from 'vue'const dynamicName = "inputDynamicRefName"
const input = useTemplateRef(dynamicName)
</script><template><div><input :ref="dynamicName" /></div>
</template>
旧版写法(3.5之前)
之前,您必须声明一个空的 refs 数组,当它与 v-for 一起注入时,达到了类似的效果。
<script setup> import { ref, useTemplateRef, onMounted } from 'vue'const list = ref([/* ... */ ])// Declare array for the dynamic collection of refs // IMPORTANT: The variable name must strictly match the value of the Template element's ref attribute! ---> itemRefs const itemRefs = ref([]) // from 3.5 can use useTemplateRef()onMounted(() => console.log(itemRefs.value)) </script><template><ul><li v-for="item in list" ref="itemRefs">{{ item }}</li></ul> </template>
使用动态模板 ref-属性值
本质上,在创建对象后,我们可以将通过 ref attribute 获得的元素作为该对象的属性添加。无需获取proxy,抑或是借助提供的组合式函数。如下例:
<script setup>
import { reactive } from 'vue'const dynamicName = "inputDynamicRefName"
const inputs = reactive({})// 注意,这里的函数和组合式函数useTempplateRef没有任何关系,仅仅是功能上相似
const setTemplateRef = (key, el) => {inputs[key] = el
}
</script><template><div><input :ref="(el) => setTemplateRef(dynamicName, el)" /></div>
</template>
参考:函数模板引用