如何在Vue 3的递归组件中正确输入useTemplateRefsList?

问题描述 投票:0回答:1

我正在使用 Composition API 和

useTemplateRefsList
中的
@vueuse/core
函数开发递归 Vue 3 组件。

我的目标是收集对递归组件的每个实例的引用。但是,我很难正确输入引用列表,因为

this
关键字在 Composition API 中不可用。

这是我的设置的简化版本:

// toto.vue
<template>
  {{ data.name }}
  <toto 
   v-for="item in data.children"
   ref="childRefs"
   :key="item.id"
   :data="item.children"
  />
</template>

<script setup lang="ts">
import { useTemplateRefsList } from '@vueuse/core';

const { data } = defineProps<{
  id: string;
  name: string;
  children?: [
   {
     id: string;
     name: string,
     children?: [...]
   }
  ]
}>();

// Attempting to type the refs list
const childRefs = useTemplateRefsList</* What type goes here? */>();
</script>

问题

我想输入

childRefs
,以便它正确表示递归组件实例的数组。

由于

this
在脚本设置语法中不可用,因此我无法直接引用组件的实例类型。

我尝试过的事情

  1. 使用
    ComponentPublicInstance
const refs = useTemplateRefsList<ComponentPublicInstance>();

但是这种类型太通用了,不能反映递归组件的实际实例。

  1. 使用
    InstanceType
const refs = useTemplateRefsList<InstanceType<typeof RecursiveComponent>>();

但是,RecursiveComponent 在其自己的声明期间尚未定义,这会产生循环依赖问题。

  1. 通过
    expose
  2. 打字

我考虑使用defineExpose来公开属性/方法并针对它们进行类型化,但这对于一个简单的递归组件来说感觉有点矫枉过正。

  1. 从另一个导出类型
    ts file
// definitionsFile.ts
import Toto from './Toto.vue';

// Without using an object, I get the following error: Type alias 'TotoType' circularly references itself.
export type TotoType = { a: InstanceType<typeof PermissionSummaryRow> };
// toto.vue
import Toto from './Toto.vue';

// 'childRefs' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer
const childRefs = useTemplateRefsList<TotoType['a']>();

// any
const test = childRefs.value[0]!;

问题

在 Vue 3 中为递归组件输入

useTemplateRefsList
的正确方法是什么?有没有办法动态引用当前组件的类型,或者有解决方法来实现这一点吗?

任何帮助或指导,我们将不胜感激!

javascript typescript vue.js recursion vueuse
1个回答
0
投票

在 Vue 3.5+ 中,您可以使用自动输入的

useTemplateRef
,推断:

游乐场

<script setup lang="ts">
import { useTemplateRef } from 'vue';
import Comp from './Comp.vue';

const arr = ['first', 'second', 'third'];

const $comps = useTemplateRef('$comps');

</script>

<template>
  <button @click="$comps.forEach($comp => $comp.addColor())">add color</button>
  <Comp ref="$comps" v-for="item of arr">{{item}}</Comp>
</template>
© www.soinside.com 2019 - 2024. All rights reserved.