vue3+ts 项目中使用svg图标配置
01 安装 svg-sprite-loader
npm i svg-sprite-loader -D
02 新建一个文件夹用来存放svg图标
src/assets
下新建文件夹icons/svg
,用来存放.svg
文件
03 创建SvgIcon组件
src/components/SvgIcon.vue
<template>
<svg :class="svgClass" aria-hidden="true">
<use :xlink:href="iconName"></use>
</svg>
</template>
<script lang="ts" setup>
import { computed } from '@vue/reactivity'
const props = defineProps({
iconClass: { type: String, required: true },
className: String,
})
const iconName = computed(() => {
return props.iconClass ? `#icon-${props.iconClass}` : '#icon'
})
const svgClass = computed(() => {
return props.className ? 'svg-icon ' + props.className : 'svg-icon'
})
</script>
<style scoped>
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
这里使用了 vue3 的 defineProps()
宏函数标注props类型,如果eslint报错ESLint: 'defineProps' is not defined.(no-undef)
,找到eslint配置文件,在env
处添加代码 ‘vue/setup-compiler-macros’: true,
"eslintConfig": {
"root": true,
"env": {
"node": true,
"vue/setup-compiler-macros": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended",
"@vue/typescript/recommended"
],
"parserOptions": {
"ecmaVersion": 2020
},
"rules": {}
},
04 修改 vue.config.js
const path = require('path')
function resolve(dir) {
return path.join(__dirname, '.', dir)
}
module.exports = {
chainWebpack: config => {
config.module.rules.delete("svg"); //重点:删除默认配置中处理svg,
config.module
.rule('svg-sprite-loader')
.test(/\.svg$/)
.include
.add(resolve('src/assets/icons')) //处理svg目录
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
},
};
05 修改 main.ts
import { createApp } from 'vue'
import App from './App.vue'
import SvgIcon from '@/components/SvgIcon.vue'
const req = require.context('@/assets/icons/svg', false, /\.svg$/)
req.keys().map(req)
createApp(App).component('SvgIcon', SvgIcon).mount('#app')
06 在组件中使用
App.vue
<template>
<SvgIcon iconClass="favicon"></SvgIcon>
</template>
iconClass 为 svg 文件名
Q.E.D.