1.访问模板引用
要在组合式 API 中获取引用,我们可以使用辅助函数 useTemplateRef()
只可以在组件挂载后才能访问模板引用
<script setup>
import { useTemplateRef, onMounted } from 'vue'
// 第一个参数必须与模板中的 ref 值匹配
const input = useTemplateRef('my-input')
onMounted(() => {
input.value.focus()
})
</script>
<template>
<input ref="my-input" />
</template>
2. v-for
中的模板引用
当在 v-for
中使用模板引用时,对应的 ref 中包含的值是一个数组,它将在元素被挂载后包含对应整个列表的所有元素
但是ref 数组并不保证与源数组相同的顺序
<script setup>
import { ref, useTemplateRef, onMounted } from 'vue'
const list = ref([
/* ... */
])
const itemRefs = useTemplateRef('items')
onMounted(() => console.log(itemRefs.value))
</script>
<template>
<ul>
<li v-for="item in list" ref="items">
{{ item }}
</li>
</ul>
</template>
3.组件上的 ref
<script setup>
import { useTemplateRef, onMounted } from 'vue'
import Child from './Child.vue'
const childRef = useTemplateRef('child')
onMounted(() => {
// childRef.value 将持有 <Child /> 的实例
})
</script>
<template>
<Child ref="child" />
</template>
注意:
(1)如果是选项式API或没有使用 <script setup>,
父组件对子组件的每一个属性和方法都有完全的访问权.
(2)但是使用了 <script setup>
的组件是默认私有的,也就是父组件无法访问子组件上的任何东西,需要添加defineExpose
宏显式暴露
<script setup>
import { ref } from 'vue'
const a = 1
const b = ref(2)
// 像 defineExpose 这样的编译器宏不需要导入
defineExpose({
a,
b
})
</script>