项目中有大量弹窗组件与公共UI组件,每次使用需要在组件内import
并且需要在components中注册,,或者在main.js中引入然后Vue.use(component)全局注册较为麻烦,尤其组件较多时候,main文件是越简洁越好;
一般拆分出来的dialog弹窗自行引入即可,公共UI一般都是全局注册,方便使用与管理
如上项目新建几个组件,AnimateNum.vue为数字改变跳动动画效果组件,echart.vue为图表组件,XBox.vue为模块盒子样式,以上组件例子在智慧城市等大屏展示项目与后台管理系统非常常见,避免繁琐复制粘贴可在index.js中一块处理,代码如下
/**
* require.context()
* arg1.检索
* arg2.是否寻找子集
* arg3.寻找规则
*/
const requireComponent = require.context('./', true, /\.vue$/)
const install = Vue => {
if (install.installed) return
install.installed = true
requireComponent.keys().forEach(filename => {
const config = requireComponent(filename)
// config.default.name为组件内的name,filename.match(/\.\/(\S*)\.vue$/)[1]为文件名称
// 一般使用文件名称较为直观(略微有点小问题),但是个人还是喜欢name规则命名,const componentName = config.default.name
// 不喜欢的直接 const componentName =filename.match(/\.\/(\S*)\.vue$/)[1]即可
const componentName = filename.match(/\.\/(\S*)\.vue$/)[1]
Vue.component(componentName, config.default || config)
})
}
export default {
install
}
// 在main,js中引入
import GlobalComponents from '@/components/Public/index'
Vue.use(GlobalComponents)
// 最好使用驼峰命名,组件内使用
<animate-num :from="fromNum" :to="toNum" :formatter="formatter" :animateEnd="animateEnd"></animate-num>
-------------做点补充:对文件名称注册命名做一下处理-----------
require.context(arg1, arg2, arg3) 若是arg2参数为true会读取Public的子文件夹中目录,一般来说若是直接使用
const componentName = config.default.name
只要确保各个组件不同name即可,若是使用filename.match(/./(\S*).vue$/)[1]即文件名称,在读取子文件夹中文件会出现**/**命名组件,感觉有点奇怪,如下图:
此时使用webpack中的require.context 第二个参数若是true 读取ttt文件夹中的echart组件出来的文件名称就是 ttt/echart ,不符合组件命名使用的习惯与规则,因此此处做一下命名处理:
代码如下:
// camelCaseChange函数主要作用是处理文件夹嵌套组件的命名处理
const camelCaseChange = (str, separator = '/') => {
// 若子文件夹有index目录读取为 ttt/index,此时可以直接处理掉 /index,处理完之后就是 ttt 组件,,
if (str.match('/index')) {
// 万一有人丧心病狂的 在ttt文件夹下嵌套index文件夹,Index文件夹下添加组件,此处再出使用camelCaseChange进行处理,
// 若文件路径是 ttt/index/echart2.vue,处理完之后组件名称为 tttEcharts,当然这种方式命名也要注意index目录下组件名称不要与上级目录重复
// 否则下面组件无法注册
return camelCaseChange(str.replace(/\/index/g, ''))
}
return str.replace(new RegExp(`${separator}(\\w)`, 'g'), str =>
// 如上图处理之后组件名称分别是:AnimateNum XBox echart tttEchart
str.slice(1).toUpperCase()
)
}
/**************************************/
// 当然有人不介意拼接index也可以直接使用下面函数处理即可
const camelCaseChange = (str, separator = '/') =>
str.replace(new RegExp(`${separator}(\\w)`, 'g'), str =>
// 如上图处理之后组件名称分别是:AnimateNum XBox echart tttEchart
str.slice(1).toUpperCase()
)
// 这里直接将匹配 '/' 替换成 ' ',并且将 / 后面第一个字母替换成大写
// 子文件夹 ttt/index/echart2.vue,处理完之后组件名称为 tttIndexEchart2,看起来也算直观
// 个人还是推荐 config.default.name 直接使用组件内的默认 name,语义化命名较为规范
/**************************************/
const requireComponent = require.context('./', true, /\.vue$/)
const install = Vue => {
if (install.installed) return
install.installed = true
requireComponent.keys().forEach(filename => {
const config = requireComponent(filename)
const componentName = camelCaseChange(filename.match(/\.\/(\S*)\.vue$/)[1])
// console.log(config.default.name, filename.match(/\.\/(\S*)\.vue$/))
Vue.component(componentName, config.default || config)
})
}
export default {
install
}