如何在 VueJS 模板中声明具有动态名称和动态组件的插槽列表?

Dan*_*ton 18 vue.js vuejs2

假设我有一个包含数据的组件:

data: function () {
  return {
    slots: [
      { Id: 1, slotName: 'apple', componentName: 'Apple' },
      { Id: 2, slotName: 'banana', componentName: 'Banana' }
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

我想将插槽列表作为作用域插槽传递给子组件。以下语法不起作用,因为您不能在模板元素上使用 v-for:

<child-component>
    <template v-for="slot in slots" :key="slot.Id" v-slot[slot.slotName]="slotProps">
        <component :is="slot.componentName" :someProp="slotProps"></component>
    </template>
</child-component>
Run Code Online (Sandbox Code Playgroud)

并且以下语法将不起作用,因为在 Vue 2.6.0+ 中any content not wrapped in a <template> using v-slot is assumed to be for the default slot

<child-component>
    <component v-for="slot in slots" :key="slot.Id"
        :is="slot.componentName" v-slot[slot.slotName]="slotProps" :someProp="slotProps"></component>
</child-component>
Run Code Online (Sandbox Code Playgroud)

以下起作用,但编译器会抛出警告并使用不推荐使用的语法:

<child-component>
    <component v-for="slot in slots" :key="slot.Id"
        :is="slot.componentName" :slot="slot.slotName" slot-scope="slotProps" :someProp="slotProps"></component>
</child-component>
Run Code Online (Sandbox Code Playgroud)

有没有办法使用未弃用的 Vue 模板语法而不使用渲染函数来实现这一点?

Eze*_*dez 16

您可以将 v-for 用于模板组件

您只需要keycomponent.

<child-component>
  <template v-for="slot in slots" v-slot:[slot.slotName]="slotProps">
    <component :key="slot.Id" :someProp="slotProps"></component>
  </template>
</child-component>
Run Code Online (Sandbox Code Playgroud)


Vic*_*iss 8

我必须动态生成插槽名称。根据 @EzequielFernandez 的回答,我使用函数做到了:

<template v-for="locale in locales" v-slot:[getSlotName(locale)]="slotProps">
 ...
</template>
Run Code Online (Sandbox Code Playgroud)
data() {
  return {
    locales: ['en', 'fr']
  }
},
methods: {
  getSlotName(locale) {
    return `locale-${locale}`
  }
}
Run Code Online (Sandbox Code Playgroud)