【vue3 $refs和特殊attr:ref 】获取子组件实例 & 规范获取Dom元素;(统称模板引用)

44 篇文章 6 订阅
29 篇文章 0 订阅

# ref (内置的特殊attribute)

  • 预期值 string | Function
  1. ref 用来给元素或子组件注册引用信息。注册内容会在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是那个 DOM 元素;如果用在子组件上,引用就指向组件实例!

  2. 关于 ref 的重要说明:在初始化组件时你不能访问 ref 绑定的对应内容 ——它们还不存在!$refs 也是非响应式的,因此你不应该试图用它在模板中做数据绑定。

  3. 尽管存在 prop 和事件,但有时你可能仍然需要在 JavaScript 中直接访问子组件。为此,可以使用 ref attribute 为子组件指定引用 ID。见 案例 2 或 3;

注意!由于vue工程项目是单页面应用,由多个组件组成的一个路由页面,也就意味着用原生DOM操作获取标签元素存在获取错误(拿到其他组件的同id、class等元素)的情况;

所以在vue里,采用 $refs + 元素 ref 值绑定来获取DOM元素的作为规范标准最合适。

 4 5种场景的代码示例:(没其他的了)

<template>
  <!-- 1. vm.$refs.p 会是 DOM 节点 -->
  <p ref="p">hello</p>

  <!-- 2. vm.$refs.child 会是子组件实例 -->
  <child-component ref="child"></child-component>

  <!-- 3. 当动态绑定时,我们可以将 ref 定义为回调函数,显式地传递元素或组件实例 -->
  <child-component :ref="(el) => fnGetEl = el"></child-component>

  <!-- 4. 组合式 API 模板引用在 v-for 内部使用时没有特殊处理。相反,请使用函数引用执行自定义处理: -->
  <!-- <div v-for="(item, i) in list" :ref='el=>refFn(el,index)'> -->
  <div v-for="(item, i) in list" :ref="el => { if (el) divs[i] = el }">
    {{ item }}
  </div>

  <!-- 新增:5. v-for的另一种绑定方式:需要 v3.2.25 及以上版本 -->
  <div v-for="(item, i) in list" ref="itemRefs">
    {{ item }}
  </div>

</template>

<script>
  import { ref, reactive, onBeforeUpdate } from 'vue'
  export default {
    setup() {
      // 案例 2:通过child就可以访问、操作该子元素所有暴露的内容。
      const child = ref(null) // 传什么乱七八糟的都行,详细见下面解释!
      // const child = ref()

      const fnGetEl = ref() // 案例 3
 
      // 案例 1: 在setup中获取dom元素的方式,变量名为ref的值,且必须要return出去!切记
      const p = ref()

      const list = reactive([1, 2, 3])
      const divs = ref([]) // 案例 4
      // 确保 list 在每次更新之前重置 ref 内容集合

      const itemRefs = ref([]) // 案例 5
      // 当在 v-for 中使用模板引用时,对应的 ref 中包含的值是一个数组,它将在元素被挂载后包含对应整个列表的所有元素:

      onBeforeUpdate(() => {
        divs.value = []
      })

      // 
      onMounted(() => {
        console.log(p.value)
        console.log(child.value)
        // ...
      })
      return {
        p,
        list,
        divs,
        itemRefs,
      }
    }
  }
</script>

setup 里由于无法使用 $refs ,所以不像 options api 里用 `this.$refs.refName`来获取对应的绑定内容。

:ref ` 传入函数的方式,对变量名没要求,符合规则即可。

ref ` 传入 string 值的绑定方式,则是 const refName = ref(); 来获取。

必须在onMounted生命周期以及之后的生命周期里,才能拿到 ref 的绑定对象!

案例1、2的解释:

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

这里我们在渲染上下文中暴露 root,并通过 ref="root",将其绑定到 div 作为其 ref。在虚拟 DOM 补丁算法中,如果 VNode 的 ref 键对应于渲染上下文中的 ref,则 VNode 的相应元素或组件实例将被分配给该 ref 的值。这是在虚拟 DOM 挂载/打补丁过程中执行的,因此模板引用只会在初始渲染之后获得赋值。

作为模板使用的 ref 的行为与任何其他 ref 一样:它们是响应式的,可以传递到 (或从中返回) 复合函数中。


# $refs

  • 类型:Object

  • 仅可读

一个对象,持有注册过 ref attribute 的所有 DOM 元素和组件实例。

$refs必须在模板渲染完成的情况下才能获取到 ref 的绑定内容。

长话短说,$refs获取ref的绑定对象,需要在 mounted 生命周期以及在 mounted 之后的周期里才能拿到,方法为`this.$refs.refName`。

$refs 没啥好讲的。。


QQ交流群:522976012  ,欢迎来玩

聚焦vue3,但不限于vue,任何前端问题,究其本质,值得讨论,研究与学习。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值