在vue项目中优雅的使用Svg

本文介绍了在Vue CLI 3项目中如何优雅地使用SVG图标,包括创建SvgIcon组件、设置图标目录结构、注册组件到全局以及修改webpack配置以支持svg-sprite-loader。通过这些步骤,可以实现SVG图标在项目中的便捷管理和使用。

在vue项目中优雅的使用Svg

我只是用来记录的,原文转载于:https://www.jb51.net/article/149452.htm

本文主要以 vue-cli3 搭建的项目为例,来聊一下如何在项目中更优雅的使用 svg 。

众所周知, vue-cli3 已经推出很长一段时间了,大家可以感受一下 vue-cli3 带来的零配置体验。But,也相应带来了一些弊端,就是如归需要修改默认的 loader 时,会比较麻烦。

好了,上正题,建议看此文章之前先去看一下张旭鑫大神的 未来必热:SVG Sprite技术介绍 ,那么我们接下来主要使用的就是上文中提到的 svg 的 use ,先上一张 vue-cli3 搭建的项目的目录,可以看到根目录下只保留了 public/ 以及 src/ ,可以说非常干净,大家可以自己创建一个。
在这里插入图片描述

在 src/components/ 下创建 SvgIcon 组件

<template>
 <svg :class="svgClass" aria-hidden="true">
 <use :xlink:href="iconName"/>
 </svg>
</template>
 
<script>
export default {
 name: 'SvgIcon',
 props: {
 iconClass: {
  type: String,
  required: true,
 },
 className: {
  type: String,
  default: '',
 },
 },
 computed: {
 iconName () {
  return `#icon-${this.iconClass}`
 },
 svgClass () {
  if (this.className) {
  return 'svg-icon ' + this.className
  } else {
  return 'svg-icon'
  }
 },
 },
}
</script>
 
<style scoped>
.svg-icon {
 width: 1em;
 height: 1em;
 vertical-align: -0.15em;
 fill: currentColor;
 overflow: hidden;
}
</style>

在 src/ 下创建一个 icons 目录,目录结构如下:
在这里插入图片描述
svg 目录主要用于存放 svg 文件,来看一下 index.js 的内容,功能就是把组件注册到全局,方便使用:

import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon' // svg组件
 
// 注册到全局
Vue.component('svg-icon', SvgIcon)
 
const requireAll = requireContext => requireContext.keys().map(requireContext)
const req = require.context('./svg', false, /\.svg$/)
requireAll(req)

当然,如果你有自己的想法或需求,可以单独引入,无需非要注册到全局。

在 main.js 中引入:

import '@/icons'

这一步就没什么好说的了,如果需要注册到全局,需要在入口文件中引入。

好了,接下来是最重要的一步:

修改默认的 loader :

大家可以去vue-cli3官网去查看具体教程,这里我只说需要修改的 loader 以及具体的代码实现。

首先需要注意的是,通过 vue-cli3 构建的项目可以初始化进行很多选择,我构建的目录更多的是以 *.config.js 的形式存在的。

在根目录下创建一个名为 vue.config.js 文件,接下来的操作都和它有关,先来看一下它完整的代码:

const path = require('path')
 
function resolve (dir) {
 return path.join(__dirname, './', dir)
}
 
module.exports = {
 chainWebpack: config => {
 config.plugin('define').tap(args => {
  const argv = process.argv
  const icourt = argv[argv.indexOf('--icourt-mode') + 1]
 
  args[0]['process.env'].MODE = `"${icourt}"`
 
  return args
 })
 // svg rule loader
 const svgRule = config.module.rule('svg') // 找到svg-loader
 svgRule.uses.clear() // 清除已有的loader, 如果不这样做会添加在此loader之后
 svgRule.exclude.add(/node_modules/) // 正则匹配排除node_modules目录
 svgRule // 添加svg新的loader处理
  .test(/\.svg$/)
  .use('svg-sprite-loader')
  .loader('svg-sprite-loader')
  .options({
  symbolId: 'icon-[name]',
  })
 
 // 修改images loader 添加svg处理
 const imagesRule = config.module.rule('images')
 imagesRule.exclude.add(resolve('src/icons'))
 config.module
  .rule('images')
  .test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
 },
 configureWebpack: {
 devServer: {
  open: true,
  // https: true,
  proxy: {
  '/user': {
   target: 'https://devadminschool.icourt.cc',
  },
  '/live': {
   target: 'https://devadminschool.icourt.cc',
  },
  },
 },
 },
}

大家忽略无关紧要的代码,重点从 svg rule loader 注释开始,其实注释已经比较详细了,就是获取默认的 loader 并进行相关的修改,主要有 svg-loader 、 images-loader ,从 vue-cli3 基础loader 中可以找到这两个 loader 的默认配置。
···javascript
// 默认的svg loader…
webpackConfig.module
.rule(‘svg’)
.test(/.(svg)(?.*)?$/)
.use(‘file-loader’)
.loader(‘file-loader’)
.options({
name: genAssetSubPath(‘img’)
})

// 默认的images loader…
webpackConfig.module
.rule(‘images’)
.test(/.(png|jpe?g|gif|webp)(?.*)?$/)
.use(‘url-loader’)
.loader(‘url-loader’)
.options(genUrlLoaderOptions(‘img’))


对比我一开始的代码可以看出,我把默认的 svg loader 配置中使用的 file-loader 改为了 svg-sprite-loader ,并排除了 node_modules ,把默认的 images-loader 配置添加了 svg ,并排除了 src/icons 目录。

我项目里面改的是veu.config.js 不用问我为什么,我只是个搬用工
```javascript
devServer: {
        host: '0.0.0.0',
        port: 80
    },
    configureWebpack: {
        name: name,
        resolve: {
            alias: {
                '@': resolve('src')
            }
        }
    },
    chainWebpack(config) {
        config.plugins.delete('preload') // TODO: need test
        config.plugins.delete('prefetch') // TODO: need test
        config.plugin('provide').use(webpack.ProvidePlugin, [{
                'window.Quill': 'quill'
            }])
            // set svg-sprite-loader  从这里开始
        config.module
            .rule('svg')
            .exclude.add(resolve('src/assets/icons'))
            .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() // 到这里结束
	
        config
            .when(process.env.NODE_ENV !== 'development',
                config => {
                    config
                        .plugin('ScriptExtHtmlWebpackPlugin')
                        .after('html')
                        .use('script-ext-html-webpack-plugin', [{
                            // `runtime` must same as runtimeChunk name. default is `runtime`
                            inline: /runtime\..*\.js$/
                        }])
                        .end()

如何使用?

可以把设计大大给的svg 或者从iconfont官网下载开源的icon的svg格式,复制到 src/icons/svg 目录下;

点击 svg 查看源码,修改 fill 属性, fill=“currentColor” ,或者 fill="" ,如果无此属性,就不用管,这样做是可以让外部控制icon的颜色,或随父元素的color;

下面代码是打开设计大大给的.svg的图片的代码

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
	 viewBox="0 0 20 20" style="enable-background:new 0 0 20 20;" xml:space="preserve">
<style type="text/css">
	.st0{fill:#FFFFFF;} // 把这个#ffffff删掉 再打开它 原本是白色的就会变成黑色的 然后就会根据字体颜色变换颜色了
</style>
<path class="st0" d="M15.3,0.2c1.6,0,2.8,1.3,2.8,2.8v13.9c0,1.6-1.3,2.8-2.8,2.8H4.1c-1.6,0-2.8-1.3-2.8-2.8V3
	c0-1.6,1.3-2.8,2.8-2.8H15.3z M7.9,9.1H6c-0.4,0-0.8,0.4-0.8,0.8c0,0.4,0.4,0.8,0.8,0.8h1.9c0.4,0,0.8-0.4,0.8-0.8
	C8.7,9.4,8.4,9.1,7.9,9.1L7.9,9.1z M9.9,5.7H6c-0.4,0-0.8,0.4-0.8,0.8C5.2,7,5.5,7.3,6,7.3h3.9c0.4,0,0.8-0.4,0.8-0.8
	C10.6,6.1,10.3,5.7,9.9,5.7L9.9,5.7z M9.9,5.7"/>
</svg>

注意svg命名和SvgIcon命名一致,看一下最终使用:

<svg-icon icon-class={icon}/>
<svg-icon icon-class="size" />
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值