如何解决二次封装antdv中select组件的插槽类型错误?

<a-select>
  <template v-for="item in Object.keys($slots)" #[item]="data">
    <slot :name="item" v-bind="data || {}"></slot>
  </template>
</a-select>

#[item]="data"item会有如下报错,大佬指点一下这里该怎么写?

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Readonly<{ notFoundContent: any; suffixIcon: any; itemIcon: any; removeIcon: any; clearIcon: any; dropdownRender: any; option: any; placeholder: any; tagRender: any; maxTagPlaceholder: any; optionLabel: any; default: any; }>'. ts(7053)
阅读 591
avatarAI BotBETA

在 Vue 3 中,动态插槽名称需要使用 v-slot:[dynamicSlotName] 的语法。因此,你应该修改你的代码为:

<a-select>
  <template v-for="item in Object.keys($slots)" :[item]="data">
    <slot :name="item" v-bind="data || {}"></slot>
  </template>
</a-select>

这里的关键改变是 #[item]="data" 改为了 :[item]="data"

然而,这并不能解决 TypeScript 报错的问题。TypeScript 报错的原因在于,你正在尝试使用一个字符串(item)来索引一个具有固定属性名的对象($slots)。$slots 的属性名通常是硬编码的,因此 TypeScript 无法确定 item 是否是 $slots 的一个有效属性名。

要解决这个问题,你需要提供更多的类型信息给 TypeScript,告诉它 item$slots 的一个有效属性名。你可以通过定义一个类型来实现这个目标,该类型包含了 $slots 可能的所有属性名。例如:

type SlotNames = 'notFoundContent' | 'suffixIcon' | 'itemIcon' | 'removeIcon' | 'clearIcon' | 'dropdownRender' | 'option' | 'placeholder' | 'tagRender' | 'maxTagPlaceholder' | 'optionLabel' | 'default';

// ...

<a-select>
  <template v-for="item in Object.keys($slots) as SlotNames" :[item]="data">
    <slot :name="item" v-bind="data || {}"></slot>
  </template>
</a-select>

在这个示例中,SlotNames 是一个字符串字面量类型,包含了所有可能的插槽名称。然后,我们使用 as 关键字将 Object.keys($slots) 的结果断言为 SlotNames 类型。这样,TypeScript 就能确定 item$slots 的一个有效属性名,因此不会报错了。

请注意,你需要根据你的实际情况来定义 SlotNames 类型,确保它包含了所有可能的插槽名称。

2 个回答

用法错了,为啥要写 #[item]="data" ?👉 #动态插槽名 - 插槽 Slots | Vue.js

<base-layout>
  <template v-slot:[dynamicSlotName]>
    ...
  </template>

  <!-- 缩写为 -->
  <template #[dynamicSlotName]>
    ...
  </template>
</base-layout>

还是说你要做动态的具名插槽?


另外你这样的组件二次封装意义何在呢?


EDIT

引用一下另外一个问答中的内容:

Vue3.3之前不支持定义插槽的类型,3.3之后支持使用 defineSlotsslots 来设置插槽的类型。

Vue3 + tsx 如何定义作用域插槽参数的类型?
Support imported types in SFC macros by yyx990803 · Pull Request #8083 · vuejs/core
Dynamic slot using v-for with typescript implicitly has type 'any' · Issue #5312 · vuejs/core

推荐问题
logo
Microsoft
子站问答
访问
宣传栏