0.
自从使用了element-plus之后就开始使用element官网推荐的unplugin-vue-components插件做组件导入,一直疑惑他到底怎么做到的组件自动导入的,最近公司裁了一部分ui/ux,ui/ux人手告急,所以公司的产品、项目、前端和后端准备做自己的套ui,既然要做这个ui那我就想是不是要做一下类型element自动导入组件的功能,所以翻了翻unplugin-vue-components源码,哎呦我去,看不懂,然后就注意到这个文件夹,唉这块不是他兼容的所有ui插件的集合和名字吗,进去看一眼;
1.
个人习惯每次看别人的代码先找抛出函数搂一眼,因为参考的element-plus的做,自然而然的打开了element-plus,全局就只有一个抛出函数叫
额,这返回的是一个list,每一项里面有两个key,一个type,一个resolve,没有用别的,type两个值一个是component(代表的组件),做的是组件的自动导入,比如element-plus的el-table的自动导入,另一个是directive(代表的指令),做的指令的自动导入,其次是另一个key(resolve),他接受的是一个函数,那他的重点就是返回值了,那看看ComponentResolver类型是个啥,
通过这个图看到type就是上面说的两个值,没有其他的了,那主要就看ComponentResolverFunction这个返回值了
一看这个返回的类型还挺多,看了一眼只有ComponentInfo类型挺有用,点过去看看
返回值有个可选的sideEffects值,翻了翻element-plus的文件看到了他
他原来做的是css的引入,那看看还有没有其他的参数,毕竟ComponentInfo类型extends了ImportInfo类型
现在能总结出他有四个key,三个可选一个必选,然后回来看这个
由此看见from是组件的引用路径,sideEffects是做css引用路径,name和as啥功能暂不确定那动手写一下
2.
0.创建项目
因为只是演示,就新建了个项目,删除现有所有组件和代码
1.
下载依赖
> npx pnpm i
2.
然后在components文件夹下创建一个公共组件
在App组件下使用这个Demonstration组件
注意这里没有引用,下面开始写unplugin-vue-components下的resolver插件
3.
因为是新项目,先下载一下unplugin-vue-components插件
> npx pnpm install -D unplugin-vue-components
修改vite.config.ts代码成这样
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import Components from "unplugin-vue-components/vite";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
vueJsx(),
Components({
resolvers:[
autoComplete()
],
dts: true,
})
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})
function autoComplete(){
}
下面开始写这个插件了
4.
写插件,看到上面代码可以看到这个插件的主要逻辑在autoComplete函数体内,他的返回值上面也说到了下面开始直接把返回值加上,因为只考虑组件的自动引入autoComplete函数写成这样
function autoComplete(){
return {
type: "component",
resolver(name:string){
return{
from:`@/components/${name}`
}
}
}
}
然后启动项目,好像出来了
然后兴冲冲的去邀功,然后被组长怼回来了,因为我们现有封装好的组件不是这样的场景,他是这样的
每个文件夹下不止一个组件,也没有像演示的项目中的那种有index入口,要在修改最少的代码下完成这个功能,然后我把演示代码的components文件夹下加了一个index文件,这个文件中的代码是这样的
import Demonstration from "./Demonstration/index.vue"
export {
Demonstration
}
然后上面说的name属性就能用上了,因为是同一出口抛出,那autoComplete函数代码就得这么写了
function autoComplete(){
return {
type: "component",
resolver(name:string){
return{
name:name,
from:`@/components`
}
}
}
}
看看项目什么样
不受影响,我又去找组长邀功了,还是被怼回来了,因为使用的时候要加统一前缀,那回来改代码
function autoComplete(){
return {
type: "component",
resolve(name:string){
return{
name:name.replace(/^Ds/,''),
from:`@/components`
}
}
}
}
完美
3.
第一次写这个文档,写的不好不要见怪,谢谢