> 文章列表 > vue3自定义svg图标组件

vue3自定义svg图标组件

vue3自定义svg图标组件

可参考:
未来必热:SVG Sprites技术介绍
懒人神器:svg-sprite-loader实现自己的Icon组件
在Vue3项目中使用svg-sprite-loader

前置知识

在页面中,虽然可以通过如下的方式使用img标签,来引入svg图标。但是,如果这个路径很长,也是比较麻烦的。

<img src="./svg/icon.svg" />

在svg里面,可以在文档中先定义Symbol,然后svg使用的时候,只须通过标识去引用指定的svg即可,Symbol的放置顺序不一定要在最前面,案例如下:
vue3自定义svg图标组件

<html><head><meta charset="utf-8"><title>SVG Sprite使用</title><style>li {font-size: 14px;margin-top: 5px;color: #369;}.webicon {width: 16px;height: 16px;margin-right: 5px;vertical-align: -2px;fill: #369;}</style>
</head><body><div style="display: none;"><svg><symbol id="liwu" viewBox="-80 -72.013 160 144.025"><pathd="M-71.949-16.039h55.974v-55.974h-55.974V-16.039z M16.102-16.039h55.975v-55.974H16.102V-16.039z M-80,32.013h64.025v-40H-80V32.013z M80,32.013v-40H16.102v40H80z M-7.923,32.013H8.051V-72.013H-7.923V32.013z M16.102,39.936 h-32.077v24.025h32.077V39.936z M64.025,39.936h-40l15.719,32.077h24.281V39.936z M-23.898,39.936h-40v32.077H-40L-23.898,39.936z"transform="matrix(1 0 0 -1 0 0)"></path></symbol><symbol id="qianbi" viewBox="-79.5 -79.5 159 159"><pathd="M79.5,32.802l-93.538-93.538l-46.699,46.699L32.802,79.5L79.5,32.802z M-79.5-32.802L-32.802-79.5H-79.5 V-32.802z"transform="matrix(1 0 0 -1 0 0)"></path></symbol><symbol id="shangchuan" viewBox="-73.623 -78.055 147.245 156.11"><pathd="M0.069,32.482L64.48-32.205H36.915v-45.85h-73.83l-0.139,45.85h-27.15L0.069,32.482z M73.623,78.055V59.632 H-73.623v18.423H73.623z"transform="matrix(1 0 0 -1 0 0)"></path></symbol></svg></div><h3>SVG Sprite使用示意</h3><ul><li><svg class="webicon"><use xlink:href="#qianbi"></use></svg>编辑信息</li><li><svg class="webicon"><use xlink:href="#liwu"></use></svg>兑换礼物</li><li><svg class="webicon"><use xlink:href="#shangchuan"></use></svg>上传文件</li></ul></div>
</body></html>

自定义svg图标步骤

1. 创建components/SvgIcon/index.vue

<template><svg class="svg-icon" aria-hidden="true"><use :xlink:href="iconName"></use></svg>
</template><script setup>
import { defineProps, computed } from 'vue'
const props = defineProps({icon: {type: String,required: true}
})const iconName = computed(() => {return `#icon-${props.icon}`
})
</script><style lang="scss" scoped>
.svg-icon {width: 1em;height: 1em;vertical-align: -0.15em;fill: currentColor;overflow: hidden;
}
</style>

2. 创建icons/index.js,

创建icons/index.js,并创建icons/svg图标所在文件夹,icon的图标就放在这个文件夹中。这里是动态的

import SvgIcon from '@/components/SvgIcon'const svgRequired = require.context('./svg', false, /\\.svg$/)
svgRequired.keys().forEach((item) => svgRequired(item))export default (app) => {app.component('svg-icon', SvgIcon)
}

3. main.js中注册SvgIcon组件

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'//import '@/assets/styles/index.scss'
import '@/assets/styles/border.css'
import '@/assets/styles/reset.css'
import '@/router/permission.js'
// import '@/router/init.js'
import {totalCommon} from '@/sys/mixinFunc.js'import SvgIcon from '@/icons'// 国际化中文
import zhCn from 'element-plus/es/locale/lang/zh-cn'const app = createApp(App)
SvgIcon(app);app.mixin(totalCommon);app.use(ElementPlus, {locale: zhCn,
})app.use(store)
app.use(router)
app.use(ElementPlus)app.mount('#app')

4. vite.config.js配置svg-sprite-loader

首先,安装scg-sprite-loader

const webpack = require('webpack');const path = require('path')
function resolve(dir) {return path.join(__dirname, dir)
}module.exports = {lintOnSave: false,chainWebpack(config) {// 设置 svg-sprite-loader// config 为 webpack 配置对象// config.module 表示创建一个具名规则,以后用来修改规则config.module// 规则.rule('svg')// 忽略.exclude.add(resolve('src/icons'))// 结束.end()// config.module 表示创建一个具名规则,以后用来修改规则config.module// 规则.rule('icons')// 正则,解析 .svg 格式文件.test(/\\.svg$/)// 解析的文件.include.add(resolve('src/icons'))// 结束.end()// 新增了一个解析的loader.use('svg-sprite-loader')// 具体的loader.loader('svg-sprite-loader')// loader 的配置.options({symbolId: 'icon-[name]'})// 结束.end()config.plugin('ignore').use(new webpack.ContextReplacementPlugin(/moment[/\\\\]locale$/, /zh-cn$/))config.module.rule('icons').test(/\\.svg$/).include.add(resolve('src/icons')).end().use('svg-sprite-loader').loader('svg-sprite-loader').options({symbolId: 'icon-[name]'}).end()}
}

CSDN档案馆