AutoImportGlobalComponents | 自动导入(注册)全局组件

64 阅读2分钟

为什要自动注册呢?直接手动注册不就好了吗?

最近在写vue项目,发现里面有很多 vue page 都会注册一个相同的 vue component。这有什么问题吗?yes!作为 IT 民工是能偷赖就偷赖。有人就会好奇了,直接在 main 里面初始化注册不就好了,确实可以这样。但是这些 vue component 都是一些需要权限才能访问的 page (在没登录之前用不到),所以就只在需要的时候才注册。

动手

接下来我们一起手摸手编写一个自动注册的 js 插件吧。

首先定义需要自动注册的 vue component 文件存放的位置,I'm 放在 Project Components 包下 image.png

import-global-component.js

I'm 在 project utils 下定义

import Vue from 'vue';

/**
 * @description 构建时所有被导入的模块都会被注册为全局组件
 * @param {*} r 上下文模块API
 */
function autoImport(r) {
    r.keys().forEach(key => {
        const component = r(key).default;
        component && Vue.component(component.name, component);
    });
}
// https://webpack.js.org/guides/dependency-management/#requirecontext
autoImport(require.context('@/components/AutoImportComponent', true, /\.vue$/));

I'm 在全局路由中注册的,因为只要注册一次就好了,所以用到了 lodash_.once(func) 函数。

import router from './router';
import { once } from 'lodash';

const autoImport = once(() => require('@/utils/import-global-component'));

router.beforeEach((to, from, next) => {
    if (to.path.startsWith('/list')) {
        autoImport();
    }
    next();
});

ps

不要使用 import() 方式导入 autoImport.js 插件,因为它与 import 不同,import() 可以动态地加载模块,并且 import() 函数是会返回一个 Promise(理解为异步就好了)。所以推荐使用 require 函数方式导入。

我就要用!!!

那就会出现下面这样的报错

image.png

原因就是页面需要的 vue component 还没有定义。

那我就是要使用 import() 方式导入怎么办?好吧,这么犟!可以使用 Promise.then 或 async/await 等机制来处理异步操作。不过还是推荐使用 require 方式!

reference

详解宏任务、微任务与事件循环 Event Loop - 掘金 (juejin.cn)

一文了解js中导入模块import、import()和require()的区别 - 掘金 (juejin.cn)