Vue3的ref使用技巧:模板引用

1,392 阅读2分钟

模板引用(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