Skip to content

模板引用

访问模板引用

虽然 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>

Released under the MIT License.