Skip to content

模板引用 (Template Refs)

介绍

旧版:对组件的 ref props传入一个ref对象,来获取组件实例。 新版:使用useTemplateRef来获取组件实例。

其实从源码角度来看, useTemplateRef 只是对 ref 的一个封装,主要是为了更好地与 Vue 3 的响应式系统集成。

TIP

具体可以看 useTemplateRef源码

在mini-vue中实现了ref引用

使用示例

vue
<script setup>
import { ref } from 'vue'
import ChildComponent from './ChildComponent.vue'
const childRef = ref(null)
function accessChild() {
  if (childRef.value) {
    // 访问子组件实例的方法或属性
    childRef.value.someMethod()
  }
  else {
    console.log('子组件尚未加载')
  }
}
</script>

<template>
  <div>
    <ChildComponent ref="childRef" />
    <button @click="accessChild">
      访问子组件
    </button>
  </div>
</template>

实现

在组件渲染更新时, 会查看组件有没有传入ref属性, 如果有, 则会将组件的实例赋值给ref对象。

typescript
if (ref !== null) {
  setRef(ref, n2)
}

设置值时, 会看组件是否有设置exposed,有的话会把exposed的值赋给ref对象,否则会将组件实例赋值给ref对象。

typescript
function setRef(rawRef, vnode) {
  const value
      = vnode.shapeFlag & ShapeFlags.STATEFUL_COMPONENT // 仅支持状态组件 不是组件就把元素的el赋值给ref
        ? vnode.component.exposed || vnode.component.proxy // 如果组件有exposed则使用exposed,否则使用组件实例
        : vnode.el
  if (isRef(rawRef)) {
    rawRef.value = value
  }
}