Vue-动态导入Vue组件

时间:2018-11-21 06:26:40

标签: javascript vue.js

我有很多组件,我想根据需要导入。我有一个下拉菜单,其中实际上包含要加载的组件列表。我试过这个例子

<component :is="componentLoader"></component>

脚本中

componentLoader () {
  return () => import('@/components/testDynamic') 
}

testDynamic 是一个组件名称(目前我正在尝试使用静态组件)。

遇到此错误

GET http://localhost:8080/0.js net::ERR_ABORTED 404
[Vue warn]: Failed to resolve async component: function () {
    return __webpack_require__.e/* import() */(0).then(__webpack_require__.bind(null, "./src/components/testDynamic.vue"));
  }
  Reason: Error: Loading chunk 0 failed.

如何解决此问题?我做错什么了吗?还是有其他方法可以动态导入组件?

4 个答案:

答案 0 :(得分:4)

您可以像这样在单个文件组件中本地注册异步动态组件:

export default {
  components: {
    'test-dynamic': () => import('@/components/testDynamic'),
    'other-dynamic': () => import('@/components/otherDynamic')
  },
  data () {
    return {
      current: 'test-dynamic'
    }
  }
}

在您的模板中:

<component :is="current"></component>

如果您注册了多个组件,则只需将current的值更改为所需的组件。

对于许多组件,可以导入一个将组件名称映射到其各自文件路径的对象,然后像以下那样注册它们:

import myComponents from '@/components'

export default {
  components: Object.keys(myComponents).reduce((obj, name) => {
    return Object.assign(obj, { [name]: () => import(myComponents[name]) })
  }, {})
  ...
}

myComponents导出为的位置:

// components/index.js
export default {
  foo: '@/path/to/Foo',
  bar: '@/path/to/Bar',
  ...
}

答案 1 :(得分:3)

我遇到了同样的问题,并且因为我使用的是Vue 3,所以这里给出的解决方案都不适合我。经过研究,我发现在Vue 3中定义动态组件(异步组件)的过程有些不同。 我希望这段代码对某人有帮助。

<template>
    <component :is="comp"></component>
</template>

<script>
//Vue 3 is having a special function to define these async functions
import {defineAsyncComponent} from "vue";

export default {
 name: "DynamicComponent",
 //I am passing the name of the Component as a prop
 props: {
     componentName:{
         type: String,
         required: true
     }
 },
 computed: {
  comp () {
      return defineAsyncComponent(() => import(`@/components/${this.componentName}.vue`))
  }
}
}
</script>

答案 2 :(得分:0)

对我有用的是等待 componentLoader 函数,因为 import 函数返回一个 promise!

async componentLoader () {
  return await import('@/components/testDynamic') 
}

答案 3 :(得分:-1)

我经常使用以下方法(Vue 2),效果很好。

以下简单示例允许动态指定要加载的组件: -因为对launchEditForm的调用仅将字符串作为参数。 如果可以将文件名表示为字符串,则可以加载它。

请务必将launchEditForm保留为“计算”属性,即不要在“方法”中对其进行定义。

如果您调用的文件不存在,则将出现以下运行时错误: 找不到模块'./components/cliente/forms/DoesNotExist.vue'

<template>
  <div>
    <button
      type="button"
@click="launchEditForm('components/clients/forms/EditContactsForm.vue')"
    >
      Edit Contacts
    </button>
    <component :is="currentEditForm" />
  </div>
</template>
<script>
export default {
  name: 'Screen42',
  data() {
    return {
      componentToDisplay: null
    };
  },
  computed: {
    currentEditForm: function() {
      if (this.componentToDisplay) {
        return () => import(`@/${this.componentToDisplay}`);
      }
      return null;
    }
  },
  methods: {
    launchEditForm(fileName) {
      this.componentToDisplay = fileName;
    }
  }
};
</script>

在以上示例中,请注意文件位于... / src / components / clients / forms / EditContactsForm.vue

这种类型的动态导入通常在模态中完成,这只是在模态内部按原样移动标签的情况。显然,我们可以使用带有布尔变量的v-if来根据需要打开和关闭模态。但是上面的代码应该说明核心点-即可以动态生成组件名称和动态加载组件。