vue集成svg-sprite-loader

本文介绍了如何在Vue项目中使用SVG图标精灵(symbol),包括工作原理、优缺点、安装配置、组件化使用方法以及全局注册和引入。通过这种方式,可以减少图片请求,提高页面加载速度,同时便于图标管理和颜色调整。但要注意,这种方法不支持多色和渐变色图标,且在部分旧版浏览器中兼容性不佳。

1.工作原理

利用svg的symbol元素,将每个icon包括在symbol中,通过use元素使用该symbol

2.svg-sprite优缺点

优点:

  1. 修改ID就可以改变图标,使用方便。
  2. 页面代码量小,维护成本低。
  3. 图标可改变颜色大小,减少重复图片的加载
  4. 减少图片请求量。

缺点:

  1. 多色、渐变色等无法通过色值改变图标颜色,需要设计师重新设计图标。
  2. 浏览器渲染性能一般。
  3. 浏览器兼容性不佳,支持ie9+,现代浏览器。

3.安装和使用

1.安装

npm install -save-dev  svg-sprite-loader@5.1.1

2.在vue.config.js中配置

function resolve (dir){
    return path.join(__dirname,dir)
}
chainWebpack(config) {
    // 已有配置排除掉svg
    config.module.rule("svg")
        .exclude.add(resolve('src/icons'));
    //配置svg
   config.module
      .rule('svg')
      .exclude.add(resolve('src/assets/icons'))// 处理SVG目录
      .end()
    config.module
      .rule('icons')
      .test(/\.svg$/)
      .include.add(resolve('src/assets/icons'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]'
      })
      .end()
  }

3.下载icon并放在 src/assets/icons/svg

下载网址:https://www.iconfont.cn/

https://icomoon.io/app/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0OcQ4Osg-1651813271025)(D:\study\项目\前端\vue+elementui\vue+elementui.assets\image-20220506125037439.png)]

4.组件化

目前使用图标需要import引入图标,svg画图,再写公共样式。可以再简化一点,将这些内容放到公共组件内。组件内容如下:

<template>
  <div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
  <svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
    <use :xlink:href="iconName" />
  </svg>
</template>

<script>
import { isExternal } from '@/utils/validate'

export default {
  name: 'SvgIcon',
  props: {
    iconClass: {
      type: String,
      required: true
    },
    className: {
      type: String,
      default: ''
    }
  },
  computed: {
    isExternal() {
      return isExternal(this.iconClass)
    },
    iconName() {
      return `#icon-${this.iconClass}`
    },
    svgClass() {
      if (this.className) {
        return 'svg-icon ' + this.className
      } else {
        return 'svg-icon'
      }
    },
    styleExternalIcon() {
      return {
        mask: `url(${this.iconClass}) no-repeat 50% 50%`,
        '-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
      }
    }
  }
}
</script>

<style scoped>
  .svg-icon {
    width: 1em;
    height: 1em;
    vertical-align: -0.15em;
    fill: currentColor;
    overflow: hidden;
  }

  .svg-external-icon {
    background-color: currentColor;
    mask-size: cover!important;
    display: inline-block;
  }
</style>

4.注册全局组件

src/assets/icons/index.js

import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'// svg component

// 注册全局组件
Vue.component('svg-icon', SvgIcon)
//  import所有符合条件的svg 三个参数:文件夹、是否使用子文件夹、正则
const req = require.context('./svg', false, /\.svg$/)
// 遍历require.context的返回模块,并导入
const requireAll = requireContext => requireContext.keys().map(requireContext)
requireAll(req)

现在只需要在页面直接使用svg-icon组件,修改icon-class就可以展示icon了。

6.在main.js中引入 上面index.js

import '@/assets/icons' // icon

7.使用

<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
Vue3 项目中使用 `svg-sprite-loader` 可以实现 SVG 图标的集中管理与高效复用,尤其适用于图标数量较多的项目。以下是一个完整的配置指南和使用方法。 ### 配置步骤 1. **安装依赖** 首先需要安装 `svg-sprite-loader` 和 `svgo-loader`(用于优化 SVG 文件): ```bash npm install svg-sprite-loader svgo-loader --save-dev ``` 2. **创建 SVG 图标目录** 在项目 `src` 目录下创建一个专门存放 SVG 图标的文件夹,例如 `icons/svg`,并将所有 SVG 图标文件放入该目录中 [^3]。 3. **配置 `vite.config.js` 或 `webpack.config.js`** 如果你使用的是 Vite 构建工具,可以在 `vite.config.js` 中添加如下配置;如果是 Webpack5,则修改 `webpack.config.js`: - **Vite 配置示例:** ```js import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; import path from 'path'; export default defineConfig({ plugins: [vue()], resolve: { alias: { '@': path.resolve(__dirname, './src'), }, }, build: { assetsDir: 'static', }, optimizeDeps: { include: ['svg-sprite-loader'], }, css: { preprocessorOptions: { scss: {}, }, }, server: { port: 3000, }, configureWebpack: { module: { rules: [ { test: /\.svg$/, loader: 'svg-sprite-loader', include: [path.resolve(__dirname, 'src/icons')], options: { symbolId: 'icon-[name]', }, }, { test: /\.svg$/, loader: 'svgo-loader', exclude: [path.resolve(__dirname, 'src/icons')], options: { plugins: [{ removeTitle: true }, { convertColors: { currentColor: '#000' } }], }, }, ], }, }, }); ``` - **Webpack 配置示例:** ```js const path = require('path'); module.exports = { entry: './src/main.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist'), }, module: { rules: [ { test: /\.svg$/, use: [ { loader: 'svg-sprite-loader', options: { symbolId: 'icon-[name]', }, }, { loader: 'svgo-loader', options: { plugins: [{ removeTitle: true }, { convertColors: { currentColor: '#000' } }], }, }, ], include: [path.resolve(__dirname, 'src/icons')], }, ], }, }; ``` 4. **封装 SVG 图标组件** 创建一个全局组件 `SvgIcon.vue` 来统一调用 SVG 图标: ```vue <template> <svg :width="size" :height="size" viewBox="0 0 24 24"> <path :d="path" :fill="color" /> </svg> </template> <script> export default { name: 'SvgIcon', props: { name: { type: String, required: true, }, color: { type: String, default: '#333', }, size: { type: [String, Number], default: 24, }, }, data() { return { path: '', }; }, mounted() { this.loadSvg(); }, methods: { async loadSvg() { const res = await import(`@/icons/${this.name}.svg?raw`); const parser = new DOMParser(); const doc = parser.parseFromString(res.default, 'image/svg+xml'); const pathElement = doc.querySelector('path'); if (pathElement) { this.path = pathElement.getAttribute('d'); } }, }, }; </script> ``` 5. **全局注册组件** 在 `main.js` 中注册 `SvgIcon` 组件为全局组件: ```js import { createApp } from 'vue'; import App from './App.vue'; import SvgIcon from './components/SvgIcon.vue'; const app = createApp(App); app.component('SvgIcon', SvgIcon); app.mount('#app'); ``` 6. **使用方式** 在模板中通过传入图标名称、颜色和尺寸来使用 SVG 图标: ```vue <template> <div> <SvgIcon name="home" color="#f00" size="32" /> </div> </template> ``` ### 注意事项 - 确保 SVG 文件命名规范且没有多余样式,避免加载时出现问题。 - 使用 `symbolId` 选项可以自定义生成的 SVG 符号 ID,便于在 HTML 中引用。 - 若项目中使用 TypeScript,需确保 SVG 文件导入方式支持类型声明 [^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

半夏_2021

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值