Vue动态组件覆盖

Vue dynamic component overwrite

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

我想要的是检查组件是否存在于覆盖的程序文件夹中并加载它的块,如果不存在默认到组件文件夹。最后会有多个程序文件夹。程序名称设置到 Vuex store ATM 中。 我知道其中一部分可以通过 Vue 标签来实现。但这需要明确声明组件,我想避免这种情况,因为最终每个组件都需要大量的导入。

有一种方法可以做到这一点。你这样做的方式是通过 Webpack 块拆分。使用动态导入 - 通过 return new 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')
}