我们一般会在项目中写一些通用的常见组件,类似 buttoninput 这种。我一般会选择将他们放在 src/components/lib 下面,每个组件建一个文件夹包裹。然后在 lib 目录下新建 index.js 用来批量获取组件,然后在 main.js 中注册。

项目文件夹关系如图所示:
folder.png

Vue CLI + Vue2

批量获取文件并注册

// FilePath: \src\components\lib\index.js
const libComponents = require.context(
  // 其组件目录的相对路径
  './',
  // 是否查询其子目录
  true,
  // 匹配基础组件文件名的正则表达式
  /([A-Z]\w+\.vue$)/
);

/**
 * 注册组件
 * @param {Object} Vue Vue
 * @param {Object} opts opts
 * @return {void}
 */
const install = (app) => {
  libComponents
    .keys()
    .forEach(fileName => {
      // 获取组件配置
      const componentsConfig = libComponents(fileName);
      // 获取组件的 PascalCase 命名
      // 获取和目录深度无关的文件名
      const componentName = (fileName
        .replace('/index.js', '')
        .split('/')
        .pop()
        .replace(/\.\w+$/, ''))
        .toLowerCase();
      // 全局注册组件
      app.component(
        `lib-${componentName}`,
        // 如果这个组件选项是通过 `export default` 导出的
        // 那么就会优先使用 `.default`
        // 否则回退到使用模块的根
        componentsConfig.default || componentsConfig
      );
    });
};

export default {
  install
};

然后在 main.js 中调用

// FilePath: main.js
import Vue from 'vue';
import App from './App.vue';
import libComponents from './components/lib';

Vue.use(libComponents);

new Vue({
  render: h => h(App)
}).$mount('#app');

Vite + Vue3

require.context 是webpack中的功能,Vite中没有,使用import.meta.glob代替:https://cn.vitejs.dev/guide/features.html#glob-import

// FilePath: \src\components\lib\index.js
// 批量加载当前目录下所有文件夹的组件
const files = import.meta.glob('./**/*.vue', { eager: true });

const install = (app) => {
  Object.keys(files).forEach(key => {
    // 获取和目录深度无关的文件名并格式化
    const componentName = (key
      .replace('/index.js', '')
      .split('/')
      .pop()
      .replace(/\.\w+$/, ''))
      .toLowerCase();
    const componentConfig = files[key];
    app.component(
      // 可以将lib换成项目的缩写
      `lib-${componentName}`,
      componentConfig.default || componentConfig
    );
  });
};
export default {
  install
};

调用方式也和Vue2有点区别

import { createApp } from 'vue';
import App from './App.vue';
import installGlobalComponents from './components/lib';

const app = createApp(App);
// 切记先use在mount
app.use(installGlobalComponents);
app.mount('#app');

Q.E.D.


我还有很多想要完成的梦想。