熟练使用svg

536 阅读3分钟

SVG

SVG:可缩放矢量图形(Scalable Vector Graphics), 使用 XML 格式定义图形

使用

一般的使用,阮老师的svg教程已经写得很清楚了,我就不多加赘述,下面我要说的是如何在vue项目中使用svg图片。

如何使用呢?我们先是用vue-cli脚手架搭建vue项目

1》在scr/assets里建立一个icons的文件,里面放置svg图片,如图 2》安装用于解析svg图片的loader:svg-sprite-loader

vue-cli对svg文件有默认的url-loader 处理,我们要使用svg 图标需单独进行配置。所以需要下载一个插件svg-sprite-loader来单独处理我们的svg图标,它是一个webpack loader,支持将多个svg打包成svg sprites

    npm install svg-sprite-loader

3》在vue.config.js里进行相关webpack的配置

使用vue-cli创建的项目,从vue-cli3开始,将webpack的基础配置全部内嵌了,这就导致我们初始化项目完成之后发现原先的webpack的config配置全部都消失不见 了,那该怎么办呢?预留了一个vue.config.js的js文件供我们 对webpack进行自定义配置。vue.config.js官方配置指南

相关配置代码:

 // 内置路径包
const path = require("path");

// 定义resolve方法,获取绝对路径
function resolve(dir) {
  return path.join(__dirname, dir);
}

module.exports = {
  // 一个函数,会接收一个基于 webpack-chain 的 ChainableConfig 实例
  // 允许对内部的 webpack 配置进行更细粒度的修改
  chainWebpack: config => {
    // 配置svg默认规则排除icons目录中svg文件处理
    config.module
      .rule("svg")
      .exclude.add(resolve("src/icons"))
      .end();
   
  // 新增icons规则,设置svg-sprite-loader处理icons目录中svg文件
  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();
   }
}

如果我们不清楚cli的默认配置,怕改错,可通过vue inspect审查webpack内部配置

4》使用svg图标

可以在main.js中引入(全局引入)或在需要引入的js文件里引入也可以,要使用的图标文件import "@/icons/svg/find.svg";

需要用到图片的地方就如下使用:

    <svg>
      <use xlink:href="#icon-qq"></use>
    </svg>

5》改进,每次都要写上面三行代码,用到什么图片还要对应去引入该图片。我们可以做一个组件,如Icon.vue

<template>
  <svg class="icon" @click="$emit('click',$event)">
    <use v-bind:xlink:href="iconName"/>
  </svg>
</template>

<script lang="js">
  const importAll =(requireContext)=>requireContext.keys().forEach(requireContext);
  
  try{importAll(require.context('../assets/icons',true,/\.svg$/));}
  catch(error){console.log("error:",error);}
  
  export default {
    name: 'Icon',
    props:['iconName']
  };
</script>

<style lang="scss" scoped>
  svg.icon{//这是icon的默认样式设置
    width: 1em; height: 1em;
    vertical-align: -0.15em;
    fill: currentColor;
    overflow: hidden;
  }
</style>

上面代码中我们使用require.context设置了当前目录下的./svg文件为上下文,使用正则匹配了它需要检测的文件名,这样它就会在当前目录的svg文件夹下去匹配符合规则的文件名 然后我们再使用importAll方法,forEach遍历。这样当该文件被调用时会遍历加载所有匹配到的文件。

6》使用,我们可以将Icon.vue组件注册为全局的组件也可注册成局部的,在需要使用svg图标的地方,如下

<Icon :iconName="你要引入的svg图标的id名"/>

完美结束

另可参考掘金上这篇文章Vue项目中优雅使用icon

与canvas的区别

Canvas 和 SVG 都允许您在浏览器中创建图形,但是它们在根本上是不同的。

SVG 是一种使用 XML 描述 2D 图形的语言。SVG 基于 XML,这意味着 SVG DOM 中的每个元素都是可用的。您可以为某个元素附加 JavaScript 事件处理器。在 SVG 中,每个被绘制的图形均被视为对象。如果 SVG 对象的属性发生变化,那么浏览器能够自动重现图形。

Canvas 通过 JavaScript 来绘制 2D 图形。Canvas 是逐像素进行渲染的。在 canvas 中,一旦图形被绘制完成,它就不会继续得到浏览器的关注。如果其位置发生变化,那么整个场景也需要重新绘制,包括任何或许已被图形覆盖的对象。

Canvas 与 SVG 的比较

下表列出了 canvas 与 SVG 之间的一些不同之处。

Canvas

  依赖分辨率
  不支持事件处理器
  弱的文本渲染能力
  能够以 .png 或 .jpg 格式保存结果图像
  最适合图像密集型的游戏,其中的许多对象会被频繁重绘

SVG

不依赖分辨率
支持事件处理器
最适合带有大型渲染区域的应用程序(比如谷歌地图)
复杂度高会减慢渲染速度(任何过度使用 DOM 的应用都不快)
不适合游戏应用

canvas vs svg

更多svg,可以查看MDNSVG教程