在Vue3项目中使用svg-sprite-loader

目录

写在前面

1.普通的svg图片使用方式

1.1路径引入

1.2 封装组件使用

2.依赖安装与loader配置

2.1 依赖安装

2.2 loader配置

3.组件SvgIcon封装

3.1 index.vue

3.2 index.ts

3.3 全局注册

4.组件使用

5.浏览器查看效果

6.编辑器中的Svg图片预览

写在后面

文章参考


Vue3+TypeScript

Webpack5+Vue-cli5

svg


写在前面

  • 本文基于Vue3+Typescript+Webpack5介绍svg-sprite-loader在项目中的使用方式,封装出一个SvgIcon全局组件
  • 对于原理方面没有进行其他的解释,感兴趣的话可以看看文末的链接,对于svg sprite以及在vue2中使用此loader的介绍或许对您有更好的理解与帮助

目录

写在前面

1.普通的svg图片使用方式

1.1路径引入

1.2 封装组件使用

2.依赖安装与loader配置

2.1 依赖安装

2.2 loader配置

3.组件SvgIcon封装

3.1 index.vue

3.2 index.ts

3.3 全局注册

4.组件使用

5.浏览器查看效果

6.浏览器查看效果

写在后面

文章参考


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相关的信息进行配置优化
  • 如果对本文对您有所帮助,还望帮忙点个赞鼓励一下,有意见或者建议欢迎留言评论

文章参考

  • 11
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值