svg图标使用
介绍:本文主要介绍svg图标的使用方法,分别介绍在vue脚手架和vite中如何使用,以及遇到的问题:use标签为0导致svg不显示、如何在导航栏使用svg图标以及跟随状态(选中、悬浮)svg图标变色。
1.svg图标的使用-vue脚手架
一开始先来介绍vue脚手架中使用svg的方法
js
// 首先要安装包
npm install svg-sprite-loader -D
components/SvgIcon/index.vue
- aria-hidden会让浏览器阅读内容的时候略过这个,避免残障人士发生歧义。
js
<template>
<div class="icon-wrapper">
<svg class="icon" aria-hidden="true">
<use :xlink:href="iconName"></use>
</svg>
</div>
</template>
<script setup>
import {computed} from "vue";
const props = defineProps({
name: {
type: String,
default: ''
}
})
let iconName = computed(()=> {
return `#icon-${props.name}`
})
</script>
<style lang="less" scoped>
.icon-wrapper {
display: inline-block;
}
.icon {
width: 100%;
height: 100%;
// 继承当前元素color的颜色,如果当前元素的color未设定,则继承祖先元素的color值。
fill: currentColor;
}
</style>
vue.config.js
js
const { defineConfig } = require('@vue/cli-service')
const path = require('path');
function resolve(dir) {
return path.join(__dirname, dir)
}
module.exports = defineConfig({
transpileDependencies: true,
configureWebpack:{
resolve: {
//配置简写路径
alias: {
'@': resolve('src'),
'assets': resolve('src/assets')
}
},
},
chainWebpack: config => {
const svgRule = config.module.rule('svg');
// 清空默认svg规则
svgRule.uses.clear();
//针对svg文件添加svg-sprite-loader规则
svgRule
.test( /.svg$/)
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
});
}
})
src/icons/index.js
- requireContext.keys().map(requireContext)主要用于批量导入时的作用
- require.context是webpack内置的方法,第一个参数:路径,第二个参数:是否检索子文件夹,第三个参数:文件的正则表达式,一般是文件名
js
const requireAll = requireContext => {
console.log('requireContext.keys().map(requireContext)',requireContext.keys().map(requireContext))
return requireContext.keys().map(requireContext)
}
// 这里要写上你svg图标的路径
const req = require.context('@/icons/svg', true, /.svg$/)
requireAll(req)
scr/plugins/svgImport.js
- 这里进行组件的注册
js
import '@/icons/index'
import SvgIcon from "@/components/SvgIcon.vue";
export default {
install: (app) => {
app.component('svg-icon', SvgIcon)
}
}
main.js
js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import svgImport from '@/plugins/svgImport'
createApp(App)
.use(router)
.use(svgImport)
.mount('#app')
页面中使用:
js
<svg-icon name="select-all-active" class="icon1"></svg-icon>
文件夹:
问题出现:
当到这里的时候,我们就会发现svg没有显示,使用开发者工具去查看,就发现svg里面的use标签宽高是0,那么为什么会这样呢?这时候我们打开控制台看看输出了什么: 这里是一个数组,数组里面是一个字符串,当你遇到这种情况的时候,那么use标签宽高很可能就是0*0.
正确的打印 这里的打印我们可以看到,也是一个数组,但是数组里面是一个对象,里面其实是我们svg图标的内容,如果没有读取到这些内容,就导致我们的use标签宽高是0*0

解决问题 把vue.config.js修改一下
js
const { defineConfig } = require('@vue/cli-service')
const path = require('path');
function resolve(dir) {
return path.join(__dirname, dir)
}
module.exports = defineConfig({
transpileDependencies: true,
configureWebpack:{
resolve: {
//配置简写路径
alias: {
'@': resolve('src'),
'assets': resolve('src/assets')
}
},
},
chainWebpack: config => {
config.module
.rule('svg')
.exclude.add(resolve('src/icons'))//svg的存储地址
.end()
config.module
.rule('icons')
.test(/.svg$/)
.include.add(resolve('src/icons'))//svg的存储地址
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
}
})
效果
2.svg图标的使用-vite
js
npm i vite-plugin-svg-icons -D
vite.config.js
js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
export default defineConfig({
plugins: [
createSvgIconsPlugin({
// 指定需要缓存的图标文件夹
iconDirs: [path.resolve(process.cwd(), 'src/icons/svg')],
// 指定symbolId格式
symbolId: "icon-[dir]-[name]"
}),
vue(),
],
resolve: {
// 设置路径别名
alias: {
'@': path.resolve( __dirname, './src'),
'*': path.resolve('')
},
}
})
components/SvgIcon/index.vue
js
<template>
<svg :class="svgClassName">
<use :xlink:href="useIconName"></use>
</svg>
</template>
<script setup>
import { computed, defineProps } from 'vue'
const props = defineProps({
name: {
type: String,
required: true
},
})
const useIconName = computed(() => `#icon-${ props.name }`)
const svgClassName = computed(() => {
if(props.name) {
return `svg-use-icon icon-${ props.name }`
}
return 'svg-use-icon'
})
</script>
<style scoped>
.svg-use-icon {
width: 100px;
height: 100px;
fill:currentColor;
}
</style>
main.js
js
import 'virtual:svg-icons-register';
import SvgIcon from "@/components/SvgIcon/index.vue";
const app = createApp(App);
// 全局注册
app.component('svg-icon', SvgIcon)
app.mount('#app')
使用:
js
<svg-icon name="select-all-active"></svg-icon>
可能遇到的报错

解决:
js
npm install fast-glob -D
3.导航栏上使用svg图标跟随状态变色
关键代码:
-
一定要给svg标签绑定上fill:currentColor
-
把每一个svg图标的fill属性改为inherit
-
一个svg图标里面会有多个fill属性,一定要全部改为inherit
效果
- 选中时候和未选中时候
- 鼠标悬浮状态
总结:
- 本文主要介绍svg图标如何在vue脚手架和vite中使用
- 解决use标签渲染宽高为0*0的问题
- 如何在导航栏上使用svg标签跟随状态变色,状态:未选中、选中、悬浮
- 有什么问题可以下方留言或者私信哦。