Intensive reading of the Vue official document series 🎉


Basic example

An.svg file would look like this:

<svg t="1626687392304" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1062"
    width="200" height="200">
    <path
        d="M512 1024a512 512 0 1 1 512-512 512 0 0 1-512 512z m-0.674909-932.398545A419.653818 419.653818 0 10 930.909091 511.255273 419.653818 419.653818 0 0 0 511.255273 91.601455z m139.892364 372.852363 h93.765818 v94.743273 h - 93.765818 v - 94.743273 - z m h93-186.181819 0. 765819 v94. 743273 h - 93.765819 v - 94.743273 - z M h93-186.181818 0. 765818 v94. 743273 h - 93.765818 v - 94.743273 - z"
        fill="# 565656" p-id="1063"></path>
</svg>
Copy the code

There are two common ways to use.svg:

  1. Just like the introduction picture, useimgOf the labelsrcProperty to introduce asvgFile.
  2. Directly to the<svg>... </svg>Tags are introduced into HTML files.

Since the first approach is more restrictive and less engineer-friendly, the second approach is more common, treating each.SVG file as a separate module.

Looking at the SVG code, you can see two important tags: < SVG /> and , where describes the specific vector path, which represents the actual graph. The < SVG /> tag is relatively fixed, allowing you to control the width, height, viewbox, etc. Now we can create an “editable SVG icon system” by encapsulating the < SVG /> tag, using external props to control its properties, and dynamically introducing the tag as a slot.

Advantages of “Editable SVG icon System” :

  • ICONS are easy to modify in real time.
  • ICONS can be used to draw.
  • The icon is inline, so no additional HTTP requests are required.
  • ICONS can be dynamically made accessible

In practice, define the IconBase. Vue component that acts as a label container.

<template>
  <svg
    xmlns="http://www.w3.org/2000/svg"
    viewBox="0 0 18 18"
    :width="width"
    :height="height"
    :aria-labelledby="iconName"
    role="presentation"
  >
    <title lang="en" :id="iconName">{{ iconName }} icon</title>
    <g :fill="iconColor">
      <slot />
    </g>
  </svg>
</template>
<script lang="ts">
import Vue from "vue";
export default Vue.extend({
  name: "IconBase".props: {
    width: {
      type: [Number.String].default: 18,},height: {
      type: [Number.String].default: 18,},iconName: {
      type: String.default: "",},iconColor: {
      type: String.default: "currentColor",}}});</script>
Copy the code

We then define the specific SVG icon component: iconsymbol.vue

<template>
   <path
    d="M512 1024a512 512 0 1 1 512-512 512 0 0 1-512 512z m-0.674909-932.398545A419.653818 419.653818 0 10 930.909091 511.255273 419.653818 419.653818 0 0 0 511.255273 91.601455z m139.892364 372.852363 h93.765818 v94.743273 h - 93.765818 v - 94.743273 - z m h93-186.181819 0. 765819 v94. 743273 h - 93.765819 v - 94.743273 - z M h93-186.181818 0. 765818 v94. 743273 h - 93.765818 v - 94.743273 - z"
  ></path>
</template>
Copy the code

Finally, combine the two components for use:

<icon-base :width="18" :height="18" :icon-name="symbol">
    <icon-symbol/>
</icon-base>
Copy the code

Of course, you can also use iconBase. Vue to dynamically match the icon component based on the icon name passed in, reducing the layer of encapsulation.

The icon that drives the drawing

The idea is to animate the tag using an animation library such as GSAP and then use $refs to manipulate the DOM directly.

Other alternatives

Another way to introduce < SVG > content directly into a page is to use an SVG Sprite.

You can configure Webpack’s SVG-Sprite-Loader to inject all SVG content into the HTML file at once and set the ID for each symbol.

This avoids inserting Svg code into HTML multiple times, such as when rendering Svg content in tables and lists.

The downside, however, is that too much SVG content can lead to slow page loading or slow compilation of compilation tools.

Finally, the article shares another SVG-related tool: The SvGo-Loader can optimize and simplify SVG code, such as removing unwanted comments and attributes.