Vue3 如何在组合式 api 中获取循环中的组件的 Ref

本文将介绍Vue 3中如何在组合式API中获取循环中的组件的ref。我们将通过在父组件中使用ref指令和v-for指令来声明和动态创建一个引用,然后在onMounted生命周期钩子中循环遍历数据来获取每个子组件的引用并存储在对应的引用中。这种方法可以让我们轻松地在循环中获取子组件的引用并进行操作,非常方便实用。

image-20230303160715411

基本用法

Vue 3 中,可以使用 refv-for 指令来在循环中获取组件的引用。

首先,在组件中,使用 ref 指令来声明一个引用:

<template>
  <div ref="myComponent"></div>
</template>

然后,在包含循环的父组件中,可以使用 v-for 指令来遍历数据并在循环中获取子组件的引用:

<template>
  <div v-for="item in items" :key="item.id">
    <my-component ref="myComponentRefs[item.id]"></my-component>
  </div>
</template>

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

export default {
  setup() {
    const myComponentRefs = ref({});

    const items = [
      { id: 1 },
      { id: 2 },
      { id: 3 }
    ];

    onMounted(() => {
      items.forEach(item => {
        myComponentRefs.value[item.id] = myComponentRefs.value[item.id].$refs.myComponent;
      });
    });

    return {
      items,
      myComponentRefs
    }
  }
}
</script>

上面的例子中,使用 ref 指令在父组件中声明了一个名为 myComponentRefs 的引用。然后,在循环中,使用 myComponentRefs[item.id] 来动态创建一个引用来存储子组件的引用。在 onMounted 生命周期钩子中,通过循环遍历 items 数组来获取每个子组件的引用并存储在对应的引用中。

注意:在 Vue 3 中,使用 ref 指令来声明一个引用会创建一个响应式的对象。因此,需要使用 myComponentRefs.value 来访问该对象的值。同时,在获取子组件的引用时,需要使用 $refs 来访问子组件的引用。

script setup的写法

在 Vue 3 的组合式 API 中,可以使用 ref 创建一个响应式的数据引用,可以在循环中使用 ref 引用组件的实例,然后通过 onMounted 钩子函数来获取实例的引用。下面是一个示例:

<template>
  <div>
    <div v-for="item in items" :key="item.id">
      <MyComponent :ref="item.ref" :data="item.data" />
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import MyComponent from './MyComponent.vue';

interface Item {
  id: number;
  data: any;
  ref: any;
}

const items: Item[] = [
  { id: 1, data: { name: 'John' }, ref: ref(null) },
  { id: 2, data: { name: 'Mary' }, ref: ref(null) },
  { id: 3, data: { name: 'Tom' }, ref: ref(null) },
];

onMounted(() => {
  items.forEach((item) => {
    item.ref.value; // Component instance
  });
});
</script>

<script lang="ts">
// MyComponent.vue
import { defineComponent } from 'vue';

export default defineComponent({
  props: ['data'],
  setup(props) {
    // ...
  },
});
</script>

在上面的示例中,items 是一个包含每个组件数据和对应 ref 的数组。v-for 循环渲染每个组件,并将组件实例的引用绑定到对应的 ref 上。在 onMounted 钩子函数中,可以遍历 items 数组来获取每个组件的实例引用,从而对组件进行操作。

需要注意的是,在 setup 函数中无法获取到循环中的组件实例,因此需要使用 ref 来引用组件实例并在 onMounted 钩子函数中获取引用。

异步组件获取

如果你的应用有这样一种情况 就是你的循环列表是通过异步获取的 比如后台请求接口获取的 然后循环生成组件 然后需要获取循环中的ref 那么上面的方案是不适用的因为上面适合的是循环的数据是挂载前就有的,那么怎么获取异步组件中的ref呢?

动态生成的 ref 可以通过 toRef 函数或 toRefs 函数将其转换为响应式的引用对象,然后再通过该引用对象来访问组件或 DOM 元素。在组合式 API 中,可以使用 toRef 函数或 toRefs 函数来将动态生成的 ref 转换为响应式的引用对象。其中,toRef 函数可以将单个 ref 对象转换为响应式的引用对象,而 toRefs 函数可以将包含多个 ref 对象的对象转换为响应式的引用对象。

下面是一个示例,演示了如何使用 toRefs 函数获取动态生成的组件或 DOM 元素的引用:

<template>
  <div v-for="(item, index) in items" :key="index">
    <MyComponent :ref="getRef(item, index)"/>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, toRefs } from 'vue'
import MyComponent from './MyComponent.vue'

const items = ref([])

setTimeout(()=>{
  items.value = [
    { id: 1, show: true },
    { id: 2, show: false },
    { id: 3, show: true }
  ]
  console.log(refs)
}, 3000)

const refs = reactive({})

const getRef = (item, index) => {
  return (el) => {
    refs[item.id] = toRefs(el)
  }
}

</script>

© 版权声明
THE END
喜欢就支持一下吧
点赞7 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容