Vuejs动态注册子组件

Register child component dynamically in Vuejs

我有一个组件,我们称它为Parent.vue(代码如下所示)。它使用Vuejs提供的<component>标签来动态渲染一个组件。

它需要一个名为 child 的属性,它描述了子组件的类型和它将使用的属性。

现在,问题是即使我的 Parent.vue 一次只渲染 1 个子组件,它也必须使用 components 对象注册所有 3 个组件。

所以,我的问题是:有没有办法根据子组件的类型动态导入注册这些子组件?类似于检查 child.type 字段并创建 components 对象的函数,仅包含所需的子对象。

如有任何帮助,我们将不胜感激

<template>
  <div>
    <component 
      :is="getComponentName(child.type)" 
      v-bind="child.props"
    >
    </component>
  </div>
</template>

<script>
  import Button from './Button.vue'
  import InputText from './InputText.vue'
  import DataTable from './DataTable.vue'

  export default{
    props:{
      child: Object
    },
    components:{
      Button,
      InputText,
      DataTable
    },
    methods:{
      getComponentName(type){
        switch(type){
          case 'button': return 'Button'
          case 'input-text': return 'InputText'
          case 'table': return DataTable
        }
      }
    }
  }
</script>

我已经按照这些思路使用了一种方法并且有效。

<template>
  <div>
    <component 
      :is="getComponentName(child.type)" 
      v-bind="child.props"
    >
    </component>
  </div>
</template>

<script>
  export default{
    props:{
      child: Object
    },
    methods:{
      getComponentName(type){
        switch(type){
          case 'button': return require('./components/Button.vue')
          case 'input-text': return require('./components/InputText.vue')
          case 'table': return require('./components/Table.vue')
        }
      }
    }
  }
</script>

由于 component 组件的 is 属性 可以接受 ComponentDefinition(请参阅更多信息 here)。所以你可以将它设置为return动态导入函数的工厂函数。

    <template>
      <div>
        <button @click='name = "Apple"'>Apple</button>
        <button @click='name = "Banana"'>Banana</button>
        <component :is='component'/>
      </div>
    </template>
    
    <script>
      export default {
        data: () => ({
          name: 'Apple'
        }),
    
        computed: {
          component () {
            let name = this.name
            return () => import(`@/components/${name}`)
          }
        }
      }
    </script>

通过这种方式,您的组件将在您使用时加载并执行,而无需显式注册。