Vue父组件使用v-for循环不同(或相同)子组件ref使用问题

  • 三个子组件:A、B、C
    在这里插入图片描述

  • 父组件:

<template>
  <h2 style="color: red">Vue父组件使用v-for循环不同(或相同)子组件ref使用问题</h2>
  <div>
    <el-button size="large" @click="aa">AAAAA</el-button>
    <el-button size="large" @click="bb">BBBBB</el-button>
  </div>

  <div v-for="(item, index) in data.tabs" :key="item.id" style="height: 150px; border: 1px solid blueviolet">
    <component :is="item.component" :message="item.name + '组件通过props传递的数据'" 
    :ref="(el) => setMyRef(el, item.refName)"></component>
  </div>
</template>

<script setup>
import { reactive, markRaw } from 'vue'
import A from '@/views/pageTest/components/A.vue'
import B from '@/views/pageTest/components/B.vue'
import C from '@/views/pageTest/components/C.vue'

//为什么使用markRaw,控制台出现警告,原因分析:
/**
将一个Vue组件对象转换为响应式对象时,可能会导致不必要的性能开销。
这是因为Vue会对响应式对象进行递归式的深度观察,在对象的每个属性上都会添加getter和setter,
以便能够在响应式对象发生变化时自动更新视图。

但是,在某些情况下,将Vue组件对象转换为响应式对象是不必要的,因为组件本身是Vue的核心概念,
已经具有响应式的功能,因此,如果你将一个Vue组件对象转换为响应式对象,
将会出现重复观察相同的对象属性的情况,导致不必要的性能开销。

为了避免这种情况,Vue建议使用markRaw方法将组件对象标记为非响应式对象,
或者使用shallowRef代替ref来创建一个浅响应式对象
使用markRaw方法将组件对象标记为非响应式对象。
*/
let myRefs = {}

// 核心
const setMyRef = (el, refName) => {
  if (el) {
    myRefs[refName] = el
  }
}

const data = reactive({
  tabs: [
    {
      id: 1,
      name: 'A',
      refName: 'refA',
      component: markRaw(A),
    },
    {
      id: 2,
      name: 'B',
      refName: 'refB',
      component: markRaw(B),
    },
    {
      id: 3,
      name: 'C',
      refName: 'refC',
      component: markRaw(C),
    },
  ],
})

const aa = () => {
  myRefs.refA?.a('A组件的方法被调用了')
}

const bb = () => {
  myRefs.refB?.b('B组件的方法被调用了')
}
</script>

<style scoped></style>

  • 效果:
    在这里插入图片描述
  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦境之冢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值