多组件/多指令注册--require.context的简单使用

require.context

require.context是webpack提供的api

require.context(directory,useSubdirectories,regExp)

  1. directory:表示检索的目录
  2. useSubdirectories:表示是否检索子文件夹
  3. regExp:匹配文件的正则表达式,一般是文件名
    例如 require.context("@/views/components",false,/.vue$/)

使用场景是:适用于多组件注册、vue多指令注册、...

----下面代码是vue3.0后的 vue2.0的需要注意----
image

//多指令注册

创建time.js---vue3.0的指令系统
export default {
  mounted(el,binding,vnode, prevVnode){
    // el.style='color:red'
    el.innerHTML=el.innerHTML+ new Date
    console.log(el,binding,vnode, prevVnode)
    console.log(el.innerHTML)
  },
  updated(el){
    el.innerHTML=el.innerHTML+ new Date
  }
}
自定义指令可参考官网 https://cn.vuejs.org/guide/reusability/custom-directives.html
vue3的指令系统的生命周期有点类似于组件的生命周期,跟vue2.0有明显的区别

下面就是核心的代码
//directive/index.js
export default {
//声明install函数 在main注入时会触发,
  install(app, option = {}) {
    // 中横线转驼峰
    const camelCase = function (s) {
      return s.replace(/-\w/g, function (x) {
        return x.slice(1).toUpperCase();
      });
    };
    //返回的是个函数 形参传递当前js路径
    const allDirs = require.context("@/directive/", false, /\.js$/);
    //定义存储器,对象的key是唯一的性质 不让定义的指令重复
    const resComponents = {}
    //进行keys()取值能取到相对路径
    allDirs.keys().forEach((comName) => {
      //取出文件名称
      let name = camelCase(comName);
      //传递当前js路径  返回相应js的modules
      const comp = allDirs(comName);
      //过滤掉install函数的js文件---意思就是加载除了index.js的js文件
      if (!comp.default.install) {
        resComponents[name.replace(/^\.\/(.*)\.\w+$/, "$1")] = comp.default;
      }
      //迭代 resComponents存储器
      for (const key in resComponents) {
        if (Object.hasOwnProperty.call(resComponents, key)) {
          const element = resComponents[key];
          //进行组件注册
          app.directive(key, element)
        }
      }
    });
  }
}

//main.js
import { createApp } from "vue";
import App from "./App.vue";
const app = createApp(App);
// 引入自定义的指令系统
import directives from "./directive";
app.use(directives)

app.use时,会往app里注入插件,并触发插件的install函数

可以看出核心部分的代码是

const allDirs = require.context("@/directive/", false, /\.js$/);
const resComponents = {}
allDirs.keys().forEach((comName) => {
   let name = camelCase(comName);
   const comp = allDirs(comName);
   resComponents[name.replace(/^\.\/(.*)\.\w+$/, "$1")] = comp.default;
})

在element官网中引入图标组件就有类似的操作

//plugins/elementSvg.js
import * as components from "@element-plus/icons-vue";
export default {
  install: (app) => {
    for (const key in components) {
      const componentConfig = components[key];
      //迭代器的 进行注册图标组件
      app.component(componentConfig.name, componentConfig);
    }
  },
};

//main.js
import { createApp } from "vue";
// 引入element图标注册
import elementIcon from "@/plugins/elementSvg";
import App from "./App.vue";
const app = createApp(App);
app.use(elementIcon)

require.context适用于 较多的相同引入操作的简化书写

posted @ 2022-08-17 15:01  xiao旭  阅读(298)  评论(0编辑  收藏  举报