Vue3.0 Composition API 模板Ref

Composition API 模板Ref

本章节使用单文件组件语法作为代码示例。

本文假定你已经阅读了Composition API 介绍和响应性基本原理。在初次接触Composition API之前应先阅读它们。

在使用Composition API时,响应式ref与模板ref的概念是统一的。 为了获得模板内的元素或者组件实例的引用,我们可以像往常一样,声明一个ref并在setup()里返回它:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
  <div ref="root">This is a root element</div>
</template>

<script>
  import { ref, onMounted } from 'vue'

  export default {
    setup() {
      const root = ref(null)

      onMounted(() => {
        // the DOM element will be assigned to the ref after initial render
        console.log(root.value) // <div>This is a root element</div>
      })

      return {
        root
      }
    }
  }
</script>

在这里,我们在渲染上下文里暴露了root,并且通过ref="root"的方式,将root作为ref绑定到div。在虚拟DOM修补算法中,如果一个虚拟节点的ref关键字在渲染上下文中关联到一个ref,这个虚拟节点的关联元素或组件实例将被赋值到这个ref的值。这是在虚拟DOM mount/patch过程中执行的,因此模板ref将只能在初始化渲染之后才能得到被赋值的值。

ref用作模板ref时,表现就像其他ref一样:都是响应式的,可以被传递到composition方法中(或被composition方法返回)。

JSX的用法

1
2
3
4
5
6
7
8
9
10
11
12
13
export default {
  setup() {
    const root = ref(null)

    return () =>
      h('div', {
        ref: root
      })

    // with JSX
    return () => <div ref={root} />
  }
}

在v-for里的用法

Composition API模板ref用在v-for里面时不会有特别的处理,而是用方法ref来执行自定义处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<template>
  <div v-for="(item, i) in list" :ref="el => { if (el) divs[i] = el }">
    {<!-- -->{ item }}
  </div>
</template>

<script>
  import { ref, reactive, onBeforeUpdate } from 'vue'

  export default {
    setup() {
      const list = reactive([1, 2, 3])
      const divs = ref([])

      // make sure to reset the refs before each update
      onBeforeUpdate(() => {
        divs.value = []
      })

      return {
        list,
        divs
      }
    }
  }
</script>