模板引用
访问模板引用
虽然 Vue 的声明性渲染模型为你抽象了大部分对 DOM 的直接操作,但在某些情况下,我们仍然需要直接访问底层 DOM 元素,此时可以使用 ref 属性。
3.5版本之后
要在组合式 API 中获取引用,我们可以使用辅助函数 useTemplateRef()
。
vue
<template>
<input type="text" ref="inputRef" />
<HelloWorld ref="helloWorldRef" />
</template>
<script setup lang="ts">
import { useTemplateRef, onMounted } from "vue";
import HelloWorld from "./components/HelloWorld.vue";
const inputRef = useTemplateRef<HTMLInputElement>("inputRef");
const helloWorldRef = useTemplateRef<InstanceType<typeof HelloWorld>>("helloWorldRef");
onMounted(() => {
console.log(inputRef);
console.log(helloWorldRef);
});
</script>
模板引用标注类型Tip
上述情况可以明确组件类型,所以可以用 InstanceType<typeof HelloWorld>
,当使用动态组件等情况时,如果不明确组件类型,且并不关心组件的具体类型时,可以使用 ComponentPublicInstance
。
vue
<script setup lang="ts">
import { useTemplateRef } from "vue";
import type { ComponentPublicInstance } from "vue";
const helloWorldRef = useTemplateRef<ComponentPublicInstance>("helloWorldRef");
</script>
3.5版本之前
提示
据 vue3 官网示例所见,在 3.5 之前需要使用 null 指明一下,但是 3.5 之后就不需要了。
vue
<template>
<input type="text" ref="inputRef" />
<HelloWorld ref="helloWorldRef" />
</template>
<script setup lang="ts">
import { ref, onMounted } from "vue";
import HelloWorld from "./components/HelloWorld.vue";
const inputRef = ref<HTMLInputElement | null>(null);
const helloWorldRef = ref<InstanceType<typeof HelloWorld> | null>(null);
onMounted(() => {
console.log(inputRef);
console.log(helloWorldRef);
});
</script>
组件访问权
如果一个子组件使用的是选项式API,而不是 <script setup>
,被引用的组件实例和该子组件的 this 完全一致,这意味着父组件对子组件的每一个属性和方法都拥有完全的访问权。
但如果使用了组合式API,即 <script setup>
,这时候子组件的属性和方法默认是私有的,此时需要通过 defineExpose
宏显式暴漏:
vue
<script setup>
import { ref } from 'vue'
const number = ref(2)
defineExpose({
number
})
</script>