# svg-sprite-loader的使用
svg-sprite-loader 将加载的 svg 图片拼接成 雪碧图,放到页面中,其它地方通过 <use>
复用
# 安装和配置 svg-sprite-loader
安装:
npm i -D svg-sprite-loader
webpack(vue.config.js) 配置:
chainWebpack: config => {
config.module
.rule("svg")
.exclude.add(resolve("src/icons/svg"))
.end()
config.module
.rule("icons")
.test(/\.svg$/)
.include.add(resolve("src/icons"))
.end()
.use("svg-sprite-loader")
.loader("svg-sprite-loader")
.options({
symbolId: "icon-[name]"
})
.end()
}
WARNING
一般情况下都会有配置 url-loader,注意urlloader 中要将 icons 文件夹排除, 不让 url-loader 处理该文件夹
关键字:exclude: [resolve('src/icons')]
# 准备工作
在 src 下建立以下目录和文件:
src
components
svg-icon.vue
icons
svg
eye.svg
index.js
utils
validate.js
上述eye.svg就是存放svg图标,如果要新增图标,可在svg文件夹下新建文件
打开阿里云图标官网点击前往 (opens new window)
搜索一个眼睛图标, 找到想要的图标,鼠标悬浮时点击下载按钮。弹出如下图所示
点击下载svg代码,并放在eye.svg文件上。
eye.svg文件如下
<svg t="1651040485477" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2294" width="200" height="200"><path d="M512 832c-156.448 0-296.021333-98.730667-418.410667-291.605333a52.938667 52.938667 0 0 1 0-56.789334C215.978667 290.730667 355.552 192 512 192c156.448 0 296.021333 98.730667 418.410667 291.605333a52.938667 52.938667 0 0 1 0 56.789334C808.021333 733.269333 668.448 832 512 832z m0-576c-129.514667 0-249.461333 83.850667-360.117333 256C262.538667 684.149333 382.485333 768 512 768c129.514667 0 249.461333-83.850667 360.117333-256C761.461333 339.850667 641.514667 256 512 256z m0 405.333333c-83.210667 0-150.666667-66.858667-150.666667-149.333333S428.789333 362.666667 512 362.666667s150.666667 66.858667 150.666667 149.333333S595.210667 661.333333 512 661.333333z m0-64c47.552 0 86.101333-38.208 86.101333-85.333333S559.552 426.666667 512 426.666667c-47.552 0-86.101333 38.208-86.101333 85.333333s38.549333 85.333333 86.101333 85.333333z" p-id="2295"></path></svg>
在components文件夹下的svg-icon.vue中粘贴以下代码
<template>
<div v-if="isExternal" :style="styleExternalIcon" :class="svgClass" 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.isExternal ? "svg-external-icon " : "") + this.className
} else {
return "svg-icon " + (this.isExternal ? "svg-external-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;
}
.svg-icon.svg-animation,
.svg-external-icon.svg-animation {
animation: rotate 2s linear infinite;
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
</style>
在icons文件夹下的index文件粘贴以下代码
import Vue from 'vue'
import SvgIcon from '@/components/svg-icon'// svg组件
// register globally
Vue.component('svg-icon', SvgIcon)
const requireAll = requireContext => requireContext.keys().map(requireContext)
const req = require.context('./svg', false, /\.svg$/)
requireAll(req)
utils/validate.js
/**
* describe 判断是否是链接
* @param {string} path
* @returns {Boolean}
*/
export function isExternal(path) {
return /^(https?:|mailto:|tel:)/.test(path)
}
最后在main.js中引入
import "@/icons" //此处使用@ 默认已配置了别名设置
接下来就可以使用svg图标了
# 使用方法
demo如下
<div class="login">
登录
<svg-icon className="svg-icon-eye" icon-class="eye"></svg-icon>
</div>
页面展示如下
使用className 来定义类名 使用 icon-class 区分使用哪个svg图标
可通过配置color属性修改svg图标颜色
<div class="login">
登录
<svg-icon className="svg-icon-eye" icon-class="eye"></svg-icon>
</div>
<style scoped>
.svg-icon-eye{
color: red;
}
</style>
展示效果如下
至此svg图标就可以使用了
也可以像img标签一样使用外部链接
<svg-icon className="svg-icon-eye" icon-class="http://www.xiaobusoft.com/static/svg-test.svg"></svg-icon>
如果想要让图标旋转,仅需添加 svg-animation
类即可
<svg-icon className="svg-icon-eye svg-animation" icon-class="http://www.xiaobusoft.com/static/svg-test.svg"></svg-icon>
# 无法改变svg图标颜色
上述配置完成后,可以正常使用svg图标,但是有时候UI设计师给的svg图标或者在icon-font网站上下载的svg图片,我们颜色使用CSS配置了,但是就是不会改变。
# 方法一
查阅svg资料发现,svg代码中的fill属性对其填充了颜色,且优先级最高。因此只要手动删除掉 fill属性值即可。显然这是一个非常笨的方法
# 方法二
使用svgo-loader
查阅svg相关资料,发现svg颜色无法更改,原因是svg代码中的fill属性对其填充了颜色,且优先级最高。一次姑妈,i
安装svgo-loader
npm i -D svgo-loader
深化vue.config.js配置
chainWebpack: config => {
config.module
.rule("svg")
.exclude.add(resolve("src/icons/svg"))
.end()
config.module
.rule("icons")
.test(/\.svg$/)
.include.add(resolve("src/icons"))
.end()
.use("svg-sprite-loader")
.loader("svg-sprite-loader")
.options({
symbolId: "icon-[name]"
})
.end()
.before("svg-sprite-loader")
.use("svgo-loader")
.loader("svgo-loader")
.options({
plugins: [
{
name: "removeAttrs",
params: {
attrs: "fill"
}
}
]
})
.end()
}
此时配置的CSS颜色,就能生效了。
它会去掉svg原有的颜色,默认为黑色。
此插件的大概意思就是帮助去除svg代码里面的fill属性
此插件不会对文件进行更改,仅运行时或者打包时生效
# 方法三
使用svgo
插件,与方法二插件差不多,用法不一致。原理也是清除svg代码里面的属性。
安装svgo
npm install svgo@1.2.2
DANGER
使用svgo时需要注意版本,2.0以前支持yml配置文件,2.0以后不再支持yml,只支持js配置文件,并新增了extendDefaultPlugins方法
在icons文件夹下新建svgo.yml文件
内容大致如下
# replace default config
# multipass: true
# full: true
plugins:
# - name
#
# or:
# - name: false
# - name: true
#
# or:
# - name:
# param1: 1
# param2: 2
- removeAttrs:
attrs:
- 'fill'
- 'fill-rule'
配置package.json文件
"scripts": {
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml"
},
执行命令去除多余属性
npm run svgo
这时候就会对 src/icons/svg 文件夹下的文件执行去除响应配置的属性操作,此操作会对文件进行修改。
其他目的
我们很多网上下载或者 Sketch
导出的 svg 会有很多冗余无用的信息,大大的增加了 svg 的尺寸,我们可以使用 svgo
对它进行优化。比如下图是用 Sketch
导出的一个 svg
无用的信息都被处理掉了。
更多详细的配置 可以在 /src/icons/svgo.yml
中进行配置。
# 总结
以上就是vue项目使用svg图标的详细内容。上述修改方法三选一。随意使用,比较懒的可以使用方法二。