封装一个自动注册插件

本文最后更新于:2023年9月4日 晚上

功能说明

能自动注册指定目录下的所有jsvue文件

  • js注册为指令,指令名称就是文件名
  • vue注册为组件,组件名为文件名的大驼峰形式

使用

vue2 版本

main.js中引入后使用即可

1
2
3
import autoRegister from './autoRegister'

Vue.use(autoRegister)

第二个值可以传入一个数组,指定自动注册的文件夹内容,如:

1
2
3
Vue.use(autoRegister, [
require.context('@/components-bak', true, /\.vue$/)
])

如无配置或者指定为空数组,则默认自动注册以下三个文件夹(无论深度):

  • src/components 文件夹开始,以下的所有vue文件注册为组件,组件名称为文件名转大驼峰
  • src/directives 文件夹开始,以下的所有js文件注册为指令,指令名称就是文件名
  • src/auto-register 文件夹开始,以下的所有vuejs对应注册

vue3 版本

同理使用use

1
2
3
4
import autoRegister from './autoRegister'

const app = createApp(App)
app.use(autoRegister)

第二个参数同上,但是自定义需要使用import.meta.glob,而且必须开启eager

1
2
3
app.use(autoRegister, [
import.meta.glob('@/components-bak/**/*.vue', { eager: true })
])

import.meta.globvite的独有功能,见文档:https://cn.vitejs.dev/guide/features.html#glob-import

引入规则见:https://github.com/mrmlnc/fast-glob#pattern-syntax

autoRegister.js

vue2 版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/**
* @author Xin-FAS
*/

// 放入require引入的对象,自动注册,js = 指令,vue = 组件
export default {
install (instance, requireDirectives = []) {
// 初始化,默认注册 components下的所有vue为组件 directives下的所有js为指令 auto-register下的js和vue
if (!requireDirectives.length) {
try {
requireDirectives.push(require.context('@/components', true, /\.vue$/))
} catch (e) {}
try {
requireDirectives.push(require.context('@/directives', true, /\.js$/))
} catch (e) {}
try {
requireDirectives.push(require.context('@/auto-register', true, /\.(js|vue)$/))
} catch (e) {}
}
// 注册
requireDirectives.forEach(directive => directive.keys().forEach(filePath => {
// 完整文件名 . 分割
const fullFilename = /.*[/\\](.*?)$/.exec('/' + filePath)[1].split('.')
;(
{
// js文件注册
js: (name, content) => instance.directive(name, content),
// vue文件注册,先转大驼峰
vue: (name, content) => instance.component(
(str => (
str = str.trim(),
str = str[0].toUpperCase() + str.slice(1),
str.replaceAll(/-(.)/g, (_, val) => val.toUpperCase())
))(name), content
)
}[fullFilename[1]]
)(
// 简单闭包,别慌
fullFilename[0],
(content => content?.default || content)(directive(filePath))
)
}))
}
}

vue3 版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/**
* @author Xin-FAS
*/

// 放入import.meta.glob引入的对象,自动注册,js = 指令,vue = 组件
export default {
install (instance, requireDirectives = []) {
// 初始化,默认注册 components下的所有vue为组件 directives下的所有js为指令 auto-register下的js和vue
if (!requireDirectives.length) {
try {
requireDirectives.push(import.meta.glob('@/components/**/*.vue', { eager: true }))
} catch (e) {}
try {
requireDirectives.push(import.meta.glob('@/directives/**/*.js', { eager: true }))
} catch (e) {}
try {
requireDirectives.push(import.meta.glob('@/auto-register/**/*.(vue|js)', { eager: true }))
} catch (e) {}
}
requireDirectives.forEach(directive => {
for (const [ filePath, importContent ] of Object.entries(directive)) {
// 完整文件名 . 分割
const fullFilename = /.*[/\\](.*?)$/.exec('/' + filePath)[1].split('.')
;(
{
// js文件注册
js: (name, content) => instance.directive(name, content),
// vue文件注册,先转大驼峰
vue: (name, content) => instance.component(
(str => (
str = str.trim(),
str = str[0].toUpperCase() + str.slice(1),
str.replaceAll(/-(.)/g, (_, val) => val.toUpperCase())
))(name), content
)
}[fullFilename[1]]
)(
// 上面执行完传入
fullFilename[0],
(content => content?.default || content)(importContent)
)
}
})
}
}

封装一个自动注册插件
https://xin-fas.github.io/2023/08/31/封装一个自动注册插件/
作者
Xin-FAS
发布于
2023年8月31日
更新于
2023年9月4日
许可协议