1.SVG在普通页面的使用
SVG
指的是利用XML
格式定义的图像,可以当做html
标签被嵌入到网页中呈现某一种效果。
在网页中使用svg
的实例:
<svg width="100" height="100" version="1.1" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" style="fill:blue;stroke-width:2;stroke:rgb(0,0,0)"/>
</svg>
2.在Vue中使用svg
在vue
项目中引入svg
,虽然可以像网页一样把一大段代码拷贝进去,但是对于模块化开发来说却显得很臃肿,于是svg
提供了use
标签,这样可以把svg
源码放在静态目录下,然后通过use
标签来引用即可。
先来看一下svg
的代码
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0" id="__SVG_SPRITE_NODE__">
<symbol xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="icon" viewBox="0 0 1024 1024" id="one">
<defs><style type="text/css"></style></defs>
<rect width="100%" height="100%" style="fill:rgb(153, 238, 172);stroke-width:2;stroke:rgb(0,0,0)"></rect>
</symbol>
</svg>
使用方法:
<svg><use xlink:href="#one"></use></svg>
- 注:
symbol
中的id
和use
中的href
要对应才行。
我们进行项目开发时,一般都是需要使用webpack进行打包处理的。而处理非js
文件,都是需要使用各种loader
来进行加载处理。目前用来处理svg
的就是svg-sprite-loader
。
高能提示
:如果vue
项目是使用ts
写的,那么还需要在shims-vue.d.ts
中增加如下代码:
declare module '*.svg'
{
const content:string;
export default content;
}
首先我们要先安装svg-sprite-loader
;
yarn add svg-sprite-loader -D
然后在vue.config.js
中配置:
const path = require('path');
module.exports = {
chainWebpack:(config)=>{
const dir=path.resolve(__dirname,'存放.svg的文件夹路径');
config.module.rule('svg-sprite').test(/\.svg$/).include.add(dir).end().use('svg-sprite-loader').loader('svg-sprite-loader').options({extract:false}).end()
config.plugin('svg-sprite').use(require('svg-sprite-loader/plugin'), [{plainSprite: true}])
config.module.rule('svg').exclude.add(dir)
}
}
这个时候我们就可以在项目中直接使用use
标签引入icon
了;
<svg><use xlink:href="#one"></use></svg>
3.封装一个Icon组件
如果项目中需要多次引用svg
图标,我们就可以封装一个Icon
组件,每次使用的时候就可以调用该组件,只要传入一个属性就可以拿到对应的svg
;
---Icon.vue---
<template>
<svg>
<use :xlink:href="'#'+name"></use>
</svg>
</template>
<script lang="ts">
const importAll = (requireContext:__WebpackModuleApi.RequireContext) => requireContext.keys().forEach(requireContext);
try{importAll(require.context('../assets/icons',true,/\.svg$/));}catch(error){console.log(error);}
export default {
props:['name'],
name:'Icon'
};
</script>
为了方便呢全局使用Icon
组件,我们可以在main.ts
中引入该组件。
import Icon from '@/components/Icon.vue';
Vue.component('Icon',Icon)
这样子在其他组件就可以使用Icon
组件了。
<Icon name='down'/>
4.关于svg无法修改颜色的解决方法。
有时候我们不小心下载了带有颜色的svg
文件,那么修改svg
的颜色可以直接打开svg
文件,然后修改里面的fill
属性即可。但是如果有很多个图片,而且多个地方用到同一个svg
文件,恰好颜色需求不一样,这样子怎么解决呢。
这个时候我们可以使用svgo-loader
进行处理了。
首先下载svgo-loader
yarn add svgo-loader
然后再vue.config.js
里面配置:
chainWebpack:(config)=>{
const dir=path.resolve(__dirname,'src/assets/icons')
config.module
.rule('svg-sprite')
.test(/\.svg$/)
.include.add(dir).end() // 包含 icons 目录
.use('svg-sprite-loader').loader('svg-sprite-loader').options({extract:false}).end()
.use('svgo-loader').loader('svgo-loader')
.tap(options=>({...options,plugins:[{removeAttrs:{attrs:'fill'}}]})).end()
config.plugin('svg-sprite').use(require('svg-sprite-loader/plugin'), [{plainSprite: true}])
config.module.rule('svg').exclude.add(dir) // 其他 svg loader 排除 icons 目录
}
}
这样子我们再不同组件使用同一个svg
文件,而且颜色不一样,我们可以在样式里面通过color
来直接指定svg
的颜色。