0

我们正在创建一个应用程序,其中接口基于 API 返回的 JSON 动态安装。它看起来像这样:

{
  "path": "Container",
  "children": [
    {
      "slot": "default",
      "path": "Banner",
      "props": {
        "items": [ "image1.jpg", "image2.jpg", "image3.jpg" ]
      }
    },

    {
      "slot": "header",
      "path": "Flex",
      "props": {
        "flow": "row"
      },
      "children": [
        {
          "slot": "default",
          "path": "Icon",
          "props": {
            "name": "mdi-forum"
          }
        },

        {
          "slot": "default",
          "text": "Example of title"
        }
      ]
    }
  ]
}

所以我ComponentLoadercomputed做一个动态创建了一个动态import,然后我还根据需要递归地注入更多的动态组件加载器,使用一个v-for通过children列表:

<template>
  <component v-if="component" :is="component" v-bind="$attrs">
    <template v-for="(child, i) of children">
      <ComponentLoader
        v-if="child.path"
        v-bind="child.props"
        :key="`${child.path}-${i}`"
        :path="child.path"
        :children="child.children"
      />
      <template v-else>{{ child.text || '' }}</template>
    </template>
  </component>
</template>

<script>
import Error from '~/components/ComponentLoaderError.vue'

export default {
  name: 'ComponentLoader',
  components: { Error },
  props: {
    path: { type: String, required: true },
    children: { type: Array, default: () => [] },
  },
  computed: {
    component() {
      if (!this.path) return null
      return () => import(`~/components/${this.path}`).then((m) => m || m.default).catch(() => Error)
    },
  },
}
</script>

它几乎可以工作了,但是所有孩子都被注入到每个加载组件的默认插槽中,这很有意义,因为我没有在通过孩子的循环期间通知所需的插槽。

受到这个答案的启发,我在with上添加了一个v-slot绑定,使用动态插槽名称注入基于已从 JSON 接收的属性的正确插槽:<template>v-forchild.slot

<template v-for="(child, i) of children" #[child.slot]>

对于每个插槽上只有一个子节点的节点,它按预期工作。但是当我有更多的孩子要分布在同一个插槽中时(比如那个 JSON 中的最后一个孩子数组),只有最后一个孩子被注入,之前覆盖了其他孩子。

那么,如何在循环中将许多子节点注入到动态命名槽中?

4

0 回答 0