一. 安装插件
- 安装vite-plugin-svg-icons插件
npm i fast-glob@3.x -D
npm i vite-plugin-svg-icons@2.x -D
- unplugin-vue-components
一个让第三方UI库无需完整引入,也无需按需引入,会自动识别并注册的插件;
这样就不会在mian.ts全局注册组件(SvgIcon)了
npm i unplugin-vue-components --save-dev
- vite-plugin-vue-setup-extend
//在setup中注册组件name
npm i vite-plugin-vue-setup-extend --save-dev
二、vite.config.js配置
import { defineConfig } from 'vite' // 帮手函数,这样不用 jsdoc 注解也可以获取类型提示
import vue from '@vitejs/plugin-vue' //识别.vue文件
import viteCompression from "vite-plugin-compression"; //gzip必备插件,开启gzip、br压缩
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' // 生成 svg 雪碧图
import vueSetupExtend from 'vite-plugin-vue-setup-extend' //在setup中注册组件name
import Components from 'unplugin-vue-components/vite'// 自动按需导入组件插件,省去大量的import操作
//path
const path = require('path');
/**
*
* 此时 TS 可能有这个错误提示:找不到模块“path”或其相应的类型声明。
* 解决方法:npm install @types/node --save-dev
*/
const resolve = (dir: string) => path.join(__dirname, dir)//__dirname 总是指向被执行 js 文件的绝对路径 EX:/d1/d2/myscript.js 文件中写了 __dirname, 它的值就是 /d1/d2
// https://vitejs.dev/config/
export default defineConfig({
//开发或生产环境服务的公共基础路径
base: './',
//作为静态资源服务的文件夹。并在构建期间复制到 outDir 的根目录,并且始终按原样提供或复制而无需进行转换。
publicDir: "public",
//用于加载 .env 文件的目录。
// envDir:"root",
//控制台输出的级别 info 、warn、error、silent
logLevel: "info",
// 设为false 可以避免 vite 清屏而错过在终端中打印某些关键信息
clearScreen: true,
//plugins配置需要使用的插件列表
plugins: [vue(), vueSetupExtend(),viteCompression({
verbose: true,
disable: false,
threshold: 10240,
algorithm: "gzip",
ext: ".gz",
}),// 自动导入svg图片
createSvgIconsPlugin({
// 指定需要缓存的图标文件夹
iconDirs: [path.resolve(process.cwd(), 'src/assets/svg')],
// 指定symbolId格式
symbolId: 'icon-[dir]-[name]',
inject: 'body-last',
customDomId: '__svg__icons__dom__'
}),
// 自动按需导入组件
Components({
// 要搜索组件的目录的相对路径
dirs: ['src/components'],
// 搜索子目录
deep: true,
// 组件的有效文件扩展名
extensions: ['vue'],
// 允许子目录作为组件的命名空间前缀。
directoryAsNamespace: false,
// 配置文件生成位置
dts: 'src/components.d.ts'
})],
// 路径相关规则
resolve: {
//配置别名
alias: {
'@': resolve('src'),// @表示当前的src目录路径
'comps': resolve('src/components'),// comps表示当前的src目录路径下components
'views': resolve('src/views'),
}
},
//本地运行配置,以及反向代理配置
server: {
host: "0.0.0.0",//指定服务器应该监听哪个 IP 地址。 如果将此设置为 0.0.0.0 或者 true 将监听所有地址,包括局域网和公网地址。
port: 80,//指定开发服务器端口
},
//打包配置
build: {
//传递给 Terser 的更多 minify 选项。 生产环境去除 console debugger
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true,
},
},
},
})
三、vite-plugin-svg-icons插件引入在main.js中
//svg 引用
import 'virtual:svg-icons-register'
四、svg图标存放路径
在assets下创建svg文件 ,在vite.config.ts,与其对应。也可以自定义路径,因人而异。
注意:
svg图标不能有中文名
五、SvgIcon组件
在components创建SvgIcon文件index.vue
<template>
<div class="svg-box">
<svg :class="svgClass" aria-hidden="true" :style="style">
<use :xlink:href="iconName" :fill="color" />
</svg>
</div>
</template>
<script lang="ts" setup name='SvgIcon'>
import { computed } from "vue"
interface Props {
name: string
width?: string
height?: string
className?: string
color?: string
}
interface Style {
width?: string
height?: string
[index: string]: any
}
const props = withDefaults(defineProps<Props>(), {
name: '',
width: '',
height: '',
className: '',
color: ''
})
const style: Style = computed(() => {
const style: Style = {}
if (props.width) {
style.width = props.width.indexOf('%') !== -1 ? props.width : props.width + 'px'
style.height = (props.height || props.width) + 'px'
}
return style
})
const iconName = computed(() => `#icon-${props.name}`)
const svgClass = computed(() => {
if (props.className) {
return `svg-icon ${props.className}`
}
return 'svg-icon'
})
</script>
<style lang="scss" scoped>
.svg-box {
display: inline-block;
.svg-icon {
position: relative;
width: 14px;
min-width: 1em;
height: 14px;
vertical-align: -2px;
}
}
</style>
六、使用
<!-- -->
<template>
<div class="box">
<SvgIcon width="28" name="analysis-chart" />
</div>
</template>
<script setup lang='ts'>
</script>
<style lang='scss' scoped>
</style>