require.context自动注册组件和路由

641 阅读2分钟

背景说明

组件是比较常用,但是为了避免在开发过程中不停地引入,或者在main.js中注册,,或者每添加一个组件就需要手动注册一次。则直接进行自动化全局注册。

由于全局注册的行为必须在根 Vue 实例 (通过 new Vue) 创建之前发生。

require.context

require.context是webpack中的一个API,能做到遍历一个文件夹中的指定文件并自动引入

require.context函数接受三个参数

require.context()传入三个参数,第一个参数是查找的目标文件路径,第二个参数是是否深层次查找(若深层次查找则会查找目标文件子文件夹里每一个文件),第三个参数是一个正则表达式用于匹配文件

  1. directory {String} -读取文件的路径

  2. useSubdirectories {Boolean} -是否遍历文件的子目录

  3. regExp {RegExp} -匹配文件的正则

语法: require.context(directory, useSubdirectories = false, regExp = /^.//);

动态路由

router.addRoutes

/************************************************************************动态添加路由 */
// 找到 router 文件夹下以 .js 命名的文件
const requireRouter = require.context(".", false, /\.js$/);

requireRouter.keys().forEach(fileName => {
    const routerConfig = requireRouter(fileName);
    // 因为得到的 fileName 格式是: './gridView.js', 所以这里我们去掉头和尾,只保留真正的文件名
    const routerName = fileName.replace(/^\.\//, "").replace(/\.\w+$/, "");

    // console.log(routerName);
    // console.log(routerConfig.default)
    // 动态添加路由
    routerConfig.default && router.addRoutes(routerConfig.default);
});
/************************************************************************动态添加路由 */

使用示例

registerRoutes

  const contextInfo = require.context('./views', true, /.vue$/)
  const routes = contextInfo.keys().map((filePath) => {
      // filePath 形如 ./Home.vue、./modifiers/capture.vue
      // path我们希望是/home、/modifiers/capture
      // 所以需要把开头的./和.vue都替换为空
      const path = filePath.toLowerCase().replace(/^\.|\.vue/g, '')
      // name的话将/home、/modifiers/capture转成小驼峰即可
      // 把开头的/先替换掉,再把第一个/后的单词变成大写就可以了
      const name = path.replace(/^\//, '').replace(/\/(\w)/, ($0, $1) => $1.toUpperCase())
      // 通过require去读取.vue文件内容
      const component = require(`./views${filePath.replace(/^\./, '')}`).default

      return {
          path,
          name,
          component
      }
  })

  return routes
  }

动态组件

vue2中基于Vue.component

在src/components下创建index.js,使用export default {} 将配置暴露出去

全局注册组件
Vue.component(
   componentName,
   如果这个组件选项是通过 `export default`
   导出的, 那么就会优先使用 `.default`,
   否则回退到使用模块的根。 componentConfig.default || componentConfig 每个组件中export default导出的配置
)

export default {
    install(Vue) {
        // 使用webpack的方法
        // require.context(文件路径, 是否深层次查找, 正则表达式)
        const requireComponent = require.context('./', true, /\.vue$/)
        // requireComponent.keys() 会找到各个组件文件的路径 包含在一个数组里面
        requireComponent.keys().forEach((ele) => {
            // requireComponent(ele).default 会得到组件对象 需要给组件设置name
            const moduleObj = requireComponent(ele).default
            Vue.component(moduleObj.name, moduleObj)
        })
    }
}

在main.js中导入,使用Vue.use()进行注册

import Vue from 'vue'
import App from './App'
// 使用Vue.use()方法注册全局组件
import plugin from '@/components'
Vue.use(plugin)
new Vue({
    render: h => h(App)
}).$mount('#app')

Vue 3基于createapp

import {
    createApp
} from 'vue'
import App from './App.vue'
import router from './router'
const app = createApp(App);

//vue3 基础组件的自动化全局注册
const requireComponent = require.context(
    // 其组件目录的相对路径
    './src/components',
    // 是否查询其子目录
    false,
    // 匹配基础组件文件名的正则表达式
    /\.vue$/
)

requireComponent.keys().forEach(fileName => {
    // 获取组件配置
    const componentConfig = requireComponent(fileName)
    // 全局注册组件
    app.component(
        componentConfig.default.name,
        // 如果这个组件选项是通过 `export default` 导出的,
        // 那么就会优先使用 `.default`,
        // 否则回退到使用模块的根。
        componentConfig.default || componentConfig
    )
})

app.use(router)
app.mount('#app')

相关参考

动态组件&异步组件:cn.vuejs.org/v2/guide/co…

equire.context自动注册:blog.51cto.com/u\_13567403…