我正在使用 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
在脚本设置语法中不可用,因此我无法直接引用组件的实例类型。
ComponentPublicInstance
:const refs = useTemplateRefsList<ComponentPublicInstance>();
但是这种类型太通用了,不能反映递归组件的实际实例。
InstanceType
:const refs = useTemplateRefsList<InstanceType<typeof RecursiveComponent>>();
但是,RecursiveComponent 在其自己的声明期间尚未定义,这会产生循环依赖问题。
expose
我考虑使用defineExpose来公开属性/方法并针对它们进行类型化,但这对于一个简单的递归组件来说感觉有点矫枉过正。
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
的正确方法是什么?有没有办法动态引用当前组件的类型,或者有解决方法来实现这一点吗?
任何帮助或指导,我们将不胜感激!
在 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>