本文从以下几个方面展开:
- 自动导入
- element-plus 集成
- SVG 图标集成
技术栈
- UI框架:一个 Vue 3 UI 框架 | Element Plus
- 自动导入工具:unplugin-auto-import
- vue 组件自动导入工具:unplugin-vue-components
自动导入
Element Plus 官方文档中推荐 按需自动导入 的方式,而此需要使用额外的插件 unplugin-auto-import 和 unplugin-vue-components 来导入要使用的组件。所以在整合 Element Plus 之前先了解下自动导入的概念和作用
概念
为了避免在多个页面重复引入 API 或 组件,由此而产生的自动导入插件来节省重复代码和提高开发效率。
插件 | 概念 | 自动导入对象 |
---|---|---|
unplugin-auto-import | 按需自动导入 API | ref、reactive、watch 等 API |
unplugin-vue-components | 按需自动导入组件 | Element-plus 组件,自定义组件等 |
安装插件依赖
pnpm install -D unplugin-auto-import unplugin-vue-components
vite.config.ts - 自动导入配置
新建 /src/types 目录用于存放自动导入函数和组件的TS类型声明文件
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
plugins: [
AutoImport({
// 自动导入 Vue 相关函数,如:ref, reactive, toRef 等
imports: ["vue"],
dts: path.resolve(pathSrc, "types", "auto-imports.d.ts"), // 指定自动导入函数TS类型声明文件路径
}),
Components({
dts: path.resolve(pathSrc, "types", "components.d.ts"), // 指定自动导入组件TS类型声明文件路径
}),
]
tsconfig.json - 自动导入TS类型声明文件引入
{
"include": ["src/**/*.d.ts"]
}
自动导入效果
运行项目 npm run dev
自动导入
1731661724391.png
集成 Element Plus
安装 Element Plus
pnpm install element-plus
配置 vite.config.ts 文件
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
plugins: [
AutoImport({
// 自动导入 vue 相关函数,如:ref, reactive, toRef 等
imports: ['vue'],
// 自动导入 Element Plus 相关函数,如:ElMessage, ElMessageBox... (带样式)
ElementPlusResolver(),
dts: path.resolve(pathSrc, 'types', 'auto-imports.d.ts'), // 指定自动导入函数TS类型声明文件路径
}),
Components({
// 自动导入 Element Plus 组件
ElementPlusResolver(),
dts: path.resolve(pathSrc, 'types', 'components.d.ts'),
}),
]
集成 SVG 图标
通过 vite-plugin-svg-icons 插件整合
Iconfont
第三方图标库实现本地图标
参考: vite-plugin-svg-icons 安装文档
- 安装依赖
pnpm install vite-plugin-svg-icons -D
- vite.config.ts 中的配置插件
// vite.config.ts
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import path from 'path'
plugins: [
createSvgIconsPlugin({
// 指定需要缓存的图标文件夹
iconDirs: [path.resolve(process.cwd(), 'src/icons')],
// 指定symbolId格式
symbolId: 'icon-[dir]-[name]',
/**
* 自定义插入位置
* @default: body-last
*/
inject?: 'body-last' | 'body-first'
/**
* custom dom id
* @default: __svg__icons__dom__
*/
customDomId: '__svg__icons__dom__',
}),
],
- 在 src/main.ts 内引入注册脚本
import 'virtual:svg-icons-register'
- 创建 src/assets/icons 目录 , 放入从 Iconfont 复制的 svg 图标
封装 svg 组件
<!-- src/components/SvgIcon/index.vue -->
<script setup lang="ts">
const props = defineProps({
prefix: {
type: String,
default: "icon",
},
iconClass: {
type: String,
required: false,
},
color: {
type: String,
},
size: {
type: String,
default: "1em",
},
});
const symbolId = computed(() => `#${props.prefix}-${props.iconClass}`);
</script>
<template>
<svg
aria-hidden="true"
class="svg-icon"
:style="'width:' + size + ';height:' + size"
>
<use :xlink:href="symbolId" :fill="color" />
</svg>
</template>
<style scoped>
.svg-icon {
display: inline-block;
outline: none;
width: 1em;
height: 1em;
vertical-align: -0.15em; /* 因icon大小被设置为和字体大小一致,而span等标签的下边缘会和字体的基线对齐,故需设置一个往下的偏移比例,来纠正视觉上的未对齐效果 */
fill: currentColor; /* 定义元素的颜色,currentColor是一个变量,这个变量的值就表示当前元素的color值,如果当前元素未设置color值,则从父元素继承 */
overflow: hidden;
}
</style>
组件使用
<template>
<el-button type="info"><svg-icon icon-class="block"/>SVG 本地图标</el-button>
</template>