SVG

  • SVG 表示可伸缩矢量图形,这是一门用于描述 2D 图形的语言,图形应用使用 XML 编写,然后 XML 由 SVG 阅读器程序呈现。

  • 支持三种类型的图形对象:矢量图形形状(例如,由直线和曲线组成的路径),图像和文本。

  • 图形对象可以进行分组,样式设置,转换和合成。

  • 功能集包括嵌套转换,剪切路径,Alpha蒙版,滤镜效果和模板对象。。

  • SVG 在 2003 年 1 月 14 日成为 W3C 推荐标准,你可以在 SVG 规范 页面中查看最新版本的 SVG 规范。

  • 大多数 Web 浏览器都可以显示 SVG,就像它们可以显示 PNG,GIF 以及 JPG 图形。IE 用户可能需要安装 Adobe SVG 阅读器以便能够在浏览器中查看 SVG。

HTML5 中嵌入 SVG

  • HTML5 允许我们直接使用<svg>标签嵌入 SVG,

    1
    <svg xmlns="http://www.w3.org/2000/svg"></svg>
  • SVG 示例, 用标签绘制一个圆:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <!DOCTYPE html>
    <head>
    <title>SVG</title>
    <meta charset="utf-8" />
    </head>
    <body>
    <h2>HTML5 SVG Circle</h2>
    <svg id="svgelem" height="200" xmlns="http://www.w3.org/2000/svg">
    <circle id="redcircle" cx="50" cy="50" r="50" fill="red" />
    </svg>
    </body>
    </html>

SVG下载

  • Font AwesomeiconmonstrIcoMoon平台提供的SVG图标

  • 通过编辑器打开其中一个.svg文件,比如facebook.svg,其代码会是这样的

    1
    2
    3
    4
    <svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="facebook-square" class="svg-inline--fa fa-facebook-square fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
    <path d="M29,0 L3,0 C1.35,0 0,1.35 0,3 L0,29 C0,30.65 1.35,32 3,32 L16,32 L16,18 L12,18 L12,14 L16,14 L16,12 C16,8.69375 18.69375,6 22,6 L26,6 L26,10 L22,10 C20.9,10 20,10.9 20,12 L20,14 L26,14 L25,18 L20,18 L20,32 L29,32 C30.65,32 32,30.65 32,29 L32,3 C32,1.35 30.65,0 29,0 Z" id="Path">
    </path>
    </svg>

Vue中使用

  • 直接使用 svg 标签体验方式不太好,使用组件的方式

使用SvgIcon

  • 在 src\components\SvgIcon\index.vue 文件中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    <template>
    <div
    v-if="isExternal"
    :style="styleExternalIcon"
    class="svg-external-icon svg-icon"
    v-on="$listeners"
    />
    <svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
    <use :xlink:href="iconName" />
    </svg>
    </template>

    <script>
    // doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
    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.className;
    } else {
    return "svg-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;
    }
    </style>
  • validate.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    /**
    * Created by PanJiaChen on 16/11/18.
    */

    /**
    * @param {string} path
    * @returns {Boolean}
    */
    export function isExternal(path) {
    return /^(https?:|mailto:|tel:)/.test(path);
    }

    /**
    * @param {string} str
    * @returns {Boolean}
    */
    export function validUsername(str) {
    // 这是预判断用户名是否有效的函数
    // const valid_map = ['admin', 'editor', 'user']
    // return valid_map.indexOf(str.trim()) >= 0
    return true;
    }
  • 注册全局组件, 在 src\icons 下新建 index.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    import Vue from "vue";
    import SvgIcon from "@/components/SvgIcon"; // svg component

    // register globally
    Vue.component("svg-icon", SvgIcon);

    // 引入项目下的svg文件
    const req = require.context("./svg", false, /\.svg$/);
    const requireAll = (requireContext) =>
    requireContext.keys().map(requireContext);
    requireAll(req);
  • main.js 中引入 src\icons

    1
    import "@/icons"; // icon
  • 安装 svg-sprite-loader, 在 vue.config.js 文件中进行配置

    1
    npm install -D svg-sprite-loader
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    const path = require("path");
    function resolve(dir) {
    return path.join(__dirname, dir);
    }

    module.exports = {
    chainWebpack(config) {
    // set svg-sprite-loader
    config.module.rule("svg").exclude.add(resolve("src/icons")).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();
    },
    };
  • 使用:将下载svg 放 icons\svg 目录下即可

    1
    2
    3
    <template>
    <svg-icon icon-class="password" />
    </template>