Vue动态组件覆盖

时间:2019-10-24 10:51:34

标签: vue.js webpack vuejs2 vue-component laravel-mix

我的项目使用Laravel和Vue(由Laravel-Mix编译)。并具有以下结构:

enter image description here

我要检查的是组件的程序文件夹中是否存在组件,然后加载它的块(如果不是默认情况下,则为components文件夹)。最后会有多个程序文件夹。程序名称设置在Vuex存储ATM中。 我知道其中一部分可以通过Vue标签实现。但这需要显式声明组件,因此我想避免这种情况,因为最终每个组件都需要大量的导入清单。

1 个答案:

答案 0 :(得分:1)

有一种方法可以完成此任务。您的方式是通过Webpack块拆分。使用动态导入-通过函数导入组件,该函数将返回新的Promises,并且在组件路径中具有'/components/${res}'之类的内容。 首先,我们创建一个Promise,尝试按如下方式加载默认组件:

export default function _getDefaultComponent(res){
return new Promise((resolve, reject) => {
    import(
        /* webpackChunkName: "js/chunk/[request]" */
        @/components/${res}
        )
        .then((component) => {
            resolve(component);
        })
        .catch((error) => {
            reject(error);
        });
}

之后,我们创建用于覆盖的函数,如下所示:

import _getDefaultComponent from "@/helpers/_getDefaultComponent";
import { program } from "@/store/program";

export default function _getComponent(res){
return new Promise((resolve, reject) => {
    let programName = program.state.programName;
    import(
        /* webpackChunkName: "js/chunk/program/[request]" */
        @/@program/${programName}/components/${res}
        )
        .then((component) => {
            resolve(component);
        })
        .catch((error) => {
            _getDefaultComponent(res)
                .then((component) => {
                    resolve(component);
                })
                .catch((error) => {
                    console.error(No Component with the name ${res}, error:, error);
                    reject(error);
                });
        });
    });
}

我们现在要做的是获取程序的名称(在本例中为Vuex),我们尝试在程序文件夹中查找某个组件,如果该组件失败,则退回到默认组件,如果失败,则控制台返回错误试图解决的组件名称。 最后使用它导入是这样的:

import _getComponent from "@/helpers/_getComponent";

之后,在您的组件中,我们就像:

components:{
    Component: () => _getComponent('Component')
}