在Vue3项目中使用svg-sprite-loader
本文基于Vue3项目介绍svg-sprite-loader在项目中的使用方式,手把手教你封装一个SvgIcon全局组件,提高svg图标复用性的同时让你的代码看起来更加优雅。
·
目录
Vue3+TypeScript
Webpack5+Vue-cli5
svg
写在前面
- 本文基于Vue3+Typescript+Webpack5介绍svg-sprite-loader在项目中的使用方式,封装出一个SvgIcon全局组件
- 对于原理方面没有进行其他的解释,感兴趣的话可以看看文末的链接,对于svg sprite以及在vue2中使用此loader的介绍或许对您有更好的理解与帮助
目录
1.普通的svg图片使用方式
1.1路径引入
- svg资源没有的话可以去这里下载阿里图标库
- 正常我们会把项目中的静态资源放在指定的一个目录,例如
assets
,使用起来就像:
<img src="../assets/svgicons/about.svg" />
1.2 封装组件使用
- 显然上面的这种方法在项目开发中不太适用,每次都需要通过路径引用
- 此次封装的目的就是简化写法,以更加简洁的方式引用图标并且具备更好的复用性
- 封装后使用如下:
<SvgIcon name="other"></SvgIcon>
//1. SvgIcon为全局组件,name表示要使用的svg图标名称
//2. other.svg图标存放于assets/svgicons目录下
2.依赖安装与loader配置
- 首先我这边项目是由Vuecli5构建的Vue3+Ts项目,Webpack5
- Webpack5内置了处理静态资源的模块,因此第一步就是需要修改一下webpack的配置;因为我们希望自己定义的svg文件不被默认的loader处理,而是用svg-sprite-loader进行处理
2.1 依赖安装
npm i svg-sprite-loader -D
// 或是
yarn add svg-sprite-loader -D
2.2 loader配置
- 打开vue.config.js文件,在chainWebpack函数中新增配置
- 这里有两种写法
2.2.1 方式一
- 如果你整个项目中的svg文件都希望使用雪碧图的方式进行处理,那么这么写
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
chainWebpack: (config) => {
const svgRule = config.module.rule('svg')
svgRule.uses.clear()
// 添加要替换的 loader
svgRule.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({symbolId: 'icon-[name]'})
}
})
2.2.2 方式二
- 或者说你只希望指定目录下的svg文件被
svg-sprite-loader
处理,其他的还是使用webpack5默认的svg处理方式,那么这么写 - 这里我的svg文件都放在了
src/assets/svgicons
目录下了
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
chainWebpack: (config) => {
// 内置的svg处理排除指定目录下的文件
config.module.rule('svg').exclude.add(resolve('src/assets/svgicons')).end()
config.module
.rule('svg-sprite-loader')
.test(/\.svg$/)
.include.add(resolve('src/assets/svgicons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
}
})
3.组件SvgIcon封装
- 在项目
src/compoent
目录下新增SvgIcon
文件夹,里面定义一个index.vue以及index.ts文件 index.vue
组件作为子组件,将来被其他组件引用,index.ts
内部定义动态引入图标的函数
3.1 index.vue
<template>
<svg class="svg-icon">
<use :xlink:href="`#icon-${props.name}`" />
</svg>
</template>
<script setup lang="ts">
type Props = {
name: string
}
const props = withDefaults(defineProps<Props>(), {
name: ''
})
</script>
<style lang="scss" scoped>
//这里可以自定义一些样式,例如:
.svg-icon {
display: inline-block;
width: 1em;
height: 1em;
overflow: hidden;
vertical-align: -0.15em;
fill: currentColor;
}
</style>
3.2 index.ts
3.2.1 关于require.context方法
- 核心就是使用了webpack内置的
require.context
方法 - 详细参数解释点击这里官网传送门
require.context(
directory, //这里指存放svg文件目录的路径
(useSubdirectories = true), //是否还搜索其子目录,默认为true
(regExp = /^\.\/.*$/), //正则匹配文件类型, 这里我们匹配 .svg 结尾的文件 /\.svg$/
(mode = 'sync') //模式,默认同步
);
- 传入我们自己的参数,创建
context(上下文)
const request = require.context('../../assets/svgicons', false, /\.svg$/)
- 以上通过
require.context()
函数来创建了自己的context(上下文)
- request返回结果为一个函数,并且此函数身上存在3个属性resolve, keys, id
- 动态引入
svgicons
文件夹下的所有文件
function importAll(req: __WebpackModuleApi.RequireContext) {
req.keys().forEach(req)
}
importAll(request)
3.2.2 最终函数
- 这里我们需要把方法暴露出去,因为
main.ts(打包的入口文件)
需要调用执行此函数
export default function importAllSvgIcons() {
try {
const request: __WebpackModuleApi.RequireContext =
require.context('../../assets/svgicons', false, /\.svg$/)
request.keys().forEach(request)
} catch(err) {
console.log(err)
}
}
3.3 全局注册
- 打开
main.ts
文件,引入我们定义的SvgIcon.vue
组件,通过app.compoent
方式全局注册 - 以及动态引入
svgicons
文件夹下面的所有文件的方法并调用
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { createPinia } from 'pinia'
import SvgIcon from '@/components/SvgIcon/index.vue'
import importAllSvgIcons from './components/SvgIcon'
const app = createApp(App)
app.component('svg-icon', SvgIcon)
importAllSvgIcons()
app.use(createPinia())
app.use(router)
app.mount('#app')
4.组件使用
- 在项目中任意组件中通过如下方式进行使用:
<SvgIcon name="msg"></SvgIcon>
- 使用效果
- 目录结构
5.浏览器查看效果
- 最后我们可以打开浏览器审查元素看看效果
- 由上图可以看到,所有的svg元素都以symbol标签的形式一个个的内嵌于一个svg元素内
- id对应着咱们设置的id格式
- 通过use标签进行svg的使用
6.编辑器中的Svg图片预览
- Vscode插件推荐:实时选中svg文件就能预览svg文件,最近发现的非常好用可以安装一下,前两个(分别是svg语法插件,预览插件)
- 效果如下,能够直接看到svg图片长啥样
写在后面
- 以上就是svg-sprite-loader在项目中的应用了,此外对于svg优化可以看看搜索svgo相关的信息进行配置优化
- 如果对本文对您有所帮助,还望帮忙点个赞鼓励一下,有意见或者建议欢迎留言评论
文章参考
- 关于Svg Sprite 未来必热:SVG Sprites技术介绍
- 关于使用svg-sprite-loader svg-sprite-loader实现自己的Icon组件
更多推荐
已为社区贡献1条内容
所有评论(0)