vue2使用svg图标集

本文介绍了如何在Vue项目中管理SVG图标,包括创建目录结构、下载并配置`svgo-loader`和`svg-sprite-loader`、在`vue.config.js`中设置规则、使用`require.context`动态导入SVG图标、以及全局注册和使用SVG组件。
摘要由CSDN通过智能技术生成

1.创建目录

icons文件下放所有后缀为svg的图标

2.下载依赖

下载依赖`svgo-loader`和`svg-sprite-loader`

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

npm install svgo-loader --save-dev

`svgo-loader`用于优化、压缩和处理SVG文件,而`svg-sprite-loader`用于将多个独立的SVG图标文件合并为一个SVG精灵文件,并提供在应用中引用和使用这些图标的便利性。 结合使用,以实现最佳的SVG图标集成和优化。

3.配置vue.config.js

const { join } = require('path')
module.exports = defineConfig({
  transpileDependencies: true,
  lintOnSave: false,
  chainWebpack: config => {
    /* 跳过 babel-loader */
    config.module.rule('js').exclude.add(path => {
      return /[\\/]src[\\/]libs[\\/].+\.js$/.test(path)
    })

    const svgSpriteIconsDir = join(__dirname, './src/components/SvgIcon/icons/')

    config.module.rule('svg').exclude.add(svgSpriteIconsDir)

    config.module
        .rule('svg-sprite')
        .after('svg')
        .test(/\.(svg)(\?.*)?$/)
        .include.add(svgSpriteIconsDir)
        .end()
        .use('svg-sprite-loader')
        .loader('svg-sprite-loader')
        .options({ symbolId: 'svgSpriteIcon__[name]' })
        .end()
        .use('svgo-loader')
        .loader('svgo-loader')
  },
})

4.创建index.js 导入所有`svg`图标

<!-- svg-sprite 图标 -->
<!-- 单色模式(非'mt-'前缀),大小继承至 font-size,颜色继承至 color -->
<!-- 多色模式('mt-'前缀),大小继承至 font-size,颜色则原始显示 -->

<!-- require.context 方法是 Webpack 提供的一个特殊方法,它接受三个参数:
1.要搜索的目录的相对路径(或绝对路径)。
2.是否搜索子文件夹。如果为 true,则递归搜索子文件夹;如果为 false,则只搜索第一层目录。
3.一个正则表达式,用于匹配文件名。

通过调用 require.context 方法并传入上述参数,你可以创建一个上下文模块。这个上下文模块拥有一些特殊方法和属性,包括 keys 方法和 resolve 方法。
keys 方法是一个函数,返回上下文模块中所有匹配的文件的相对路径字符串组成的数组。
resolve 方法是一个函数,接受一个路径参数,并返回该路径在上下文模块中的模块 ID。
-->
<script>
    let requireCtx
    try {
        requireCtx = require.context(
            './icons/',
            false, // 不解析子文件夹
            /\.svg$/,
        )
    } catch (err) {
        if (
            /* 允许文件夹缺失(处理 git 无法提交空文件夹的情况) */
            err.code === 'MODULE_NOT_FOUND'
        ) {
            requireCtx = () => {}
            requireCtx.keys = () => []
        } else {
            throw err
        }
    }

    const fileNames = requireCtx.keys()
    const names = Object.freeze(
        fileNames.map(fileName =>  //取出没有后缀的文件名
            fileName
                .split(/[/\\]+/)
                .pop()             //pop() ,移除并返回数组的最后一个元素。
                .replace(/\.\w+$/, ''),    //  /\.\w+$/ 匹配以点号后跟一个或多个字母、数字或下划线结尾的字符串。. 匹配任意字符(除了换行符),而 \w 匹配任意字母、数字或下划线字符。+ 是一个量词,表示匹配前面的模式一次或多次。$ 是一个锚点,表示匹配字符串的结尾。
        ),
    )
    fileNames.forEach(fileName => requireCtx(fileName))

    export { names }
    export default {
        name: 'SvgIcon',
        props: {
            icon: {
                type: String,
                required: true,
            },
        },
    }
</script>

<template>
    <i :class="['svg-icon', `svg-icon-${icon}`]">
        <svg class="svg-icon__icon">
            <use :xlink:href="`#svgSpriteIcon__${icon}`" />
        </svg>
    </i>
</template>

<style lang="less">
  .svg-icon {
    display: inline-block;
    width: 1em;
    height: 1em;
    vertical-align: -0.165em;
    font-style: normal;
    line-height: 1;
    &__icon {
      display: block;
      overflow: hidden;
      width: 100%;
      height: 100%;
      fill: currentColor;
    }
  }

  [id^='svgSpriteIcon__']:not([id^='svgSpriteIcon__mt-']) {
    // svgo-loader 会自动计算内联样式并应用到 fill 属性上
    [fill]:not([fill='none']):not([fill='transparent']) {
      fill: currentColor;
    }
    // svgo-loader 会自动计算内联样式并应用到 stroke 属性上
    [stroke]:not([stroke='none']):not([stroke='transparent']) {
      stroke: currentColor;
    }
  }
</style>

5.全局注册组件

可创建一个装全局的js文件

index.js的代码为:

/**
 * !!!慎用全局注册
 * 这里只适合注册,具体实现需拆分到单独的文件
 */
import Vue from 'vue'

const SvgIcon = function() {
    return import(/* webpackChunkName: "low-priority" */ '@/components/SvgIcon/index.vue')
}

/* 全局组件 Vue.component */
Vue.component('svg-icon', SvgIcon)

6.引入全局文件

在main.js中引入全局文件

7.使用

icon名称一定要对应!

可单独设置类名来控制svg的颜色和大小

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值