Vue3$Data-TemplateRef
0. Template Ref in Big Picture
数据可以分为两种:主动地创造,被动地使用。
比如想要养一条狗。买/领取/收养是“主动地创造”。当有了狗之后,给狗取名就是“被动地使用”。
在 Vue 中,ref / reactive,props,computed 都属于主动地创造。而 template refs 则属于被动地使用。
Template refs 用于标识已经存在的 DOM 元素/组件。
1. 定义和使用 ref
- 定义:
- 在 template 中给标签/组件加上
ref属性 - 在 script 中声明和 template 中同名的 ref
- 在 template 中给标签/组件加上
- 使用:onMounted 之后使用
<script setup>
import { ref, onMounted } from 'vue'
// 声明一个 ref 来存放该元素的引用
const input = ref(null)
// access refs after mounted
onMounted(() => {
input.value.focus()
})
</script>
<template>
<input ref="input" />
</template>
watchEffect(() => {
if (input.value) {
input.value.focus()
} else {
// 此时还未挂载,或此元素已经被卸载(例如通过 v-if 控制)
}
})
2. Template Refs 的分类
在 template 中,ref 可以分为以下几类:
- 普通字符串(上面的例子)
- 数组(不保证顺序)
- 函数
// 数组,v-for
<script setup>
import { ref, onMounted } from 'vue'
const list = ref([
/* ... */
])
const itemRefs = ref([])
onMounted(() => console.log(itemRefs.value))
</script>
<template>
<ul>
<li v-for="item in list" ref="itemRefs">
{{ item }}
</li>
</ul>
</template>
<input :ref="(el) => { /* 将 el 赋值给一个数据属性或ref变量 */ }">
卸载时el是null
3. 注意事项
- onMounted 之后才能获取到 ref
- 组件实例的 ref 对象获取到的数据,自动解包了该组件数据中的 ref(此 ref 指的是响应式数据)