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的颜色。