模板引用(template refs),通过在元素/组件上使用ref这个attribute,使得我们能够去操作真实DOM或者组件实例:
<template>
<input ref="inputRef" />
<my-component ref="myComponentRef" />
</template>
<script setup>
import MyComponent from './MyComponent.vue'
import { ref } from 'vue'
const inputRef = ref(null)
const myComponentRef = ref(null)
</script>
访问引用
如果ref attribute绑定的是一个元素,那么可以在组件被挂载之后,通过绑定的ref对象.value的方式来访问到对应的元素或组件实例
引用结合v-for使用
ref attribute也可以结合v-for使用,从而绑定v-for遍历生成的多个元素/组件实例,对应的ref对象.value的值将会是一个数组
<template>
<ul>
<li v-for="item in list" ref="itemRefs">
{{ item }}
</li>
</ul>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const list = ref([
/* ... */
])
const itemRefs = ref([])
onMounted(() => console.log(itemRefs.value))
</script>
注意:数组中元素的顺序并不能保证跟遍历的顺序一致
函数引用
ref atrribute除了绑定一个字符串,还可以绑定一个函数,这个函数会在被绑定的组件更新时被调用。通过这种方式我们可以更加灵活地获取元素引用。这个函数会接收元素引用作为第一个参数:
<template>
<input type="text" :ref="getRef">
<test-cpn :ref="getRef"/>
</template>
<script setup>
const getRef = (el) => {
console.log(el); // 如果绑定的是一个元素,那么会直接传入对应的DOM
if(el) {
console.log(el.$el); // 如果绑定的是一个组件,那么会传入对应的组件实例
}
}
</script>
注意:在元素被卸载之后,传入的参数将会是null
组件引用
通过在子组件上绑定ref,我们可以获取到对应的子组件实例。
如果这个子组件使用的是options API或者没有使用<script setup>这种写法,那么这个子组件实例将会等同于子组件的this。也就意味着我们可以在父组件中访问到子组件完整的属性和方法。
这种方式使得我们可以在父组件中创建一些高耦合的细节实现。因此,对于组件引用我们应该只在必须的情况下在使用。在大多数情况下,父子组件的互动应该优先使用标准的props和emits接口。
在子组件使用<script setup>语法的情况中,编写在<script setup>中 的变量/方法默认是私有的。如果希望能够被外部访问到,我们可以使用Vue提供的defineExpose宏