Ali icon library iconfont, symbol reference of svg icon, combined with svg-sprite-loader (use svg elegantly)

svg-sprite-loaderFunction: Splice the loaded svg image into a Sprite image, and put it on the page, so that it
can be reused in other places (it can be understood as turning SVG into HTML symbol tags, introducing elegance and smoothness)

1. Install svg-sprite-loader

yarn add svg-sprite-loader -D

Two, configure webpack

vue.config.js file

const path = require("path");
const resolve = dir => path.join(__dirname, "./", dir);
module.exports = {
    
    
  chainWebpack: config => {
    
    
    config.module
      .rule("icons")
      .test(/\.svg$/)
     .include.add(resolve("src/icons")) //svg目录
      .end()
      .use("svg-sprite-loader")
      .loader("svg-sprite-loader")
      .options({
    
    
        symbolId: "icon-[name]"
      });
    config.module
      .rule("svg")
      .exclude.add(resolve("src/icons"))
      .end();
  }
};

Three, package SvgIcon components

<template>
  <svg :class="className" aria-hidden="true" v-on="$listeners">
    <use :xlink:href="icon" />
  </svg>
</template>

<script>
export default {
    
    
  name: "SvgIcon",
  props: {
    
    
    iconName: {
    
    
      type: String,
      required: true
    },
    iconClass: {
    
    
      type: String,
      default: ""
    }
  },
  computed: {
    
    
    icon() {
    
    
      return `#icon-${
      
      this.iconName}`;
    },
    className() {
    
    
      if (this.iconClass) {
    
    
        // 如果父组件给子组件传了iconClass,则将该类名用于svg的class上
        return "svg-icon " + this.iconClass;
      } else {
    
    
        return "svg-icon";
      }
    }
  }
};
</script>

<style scoped>
.svg-icon {
    
    
  /*将icon大小设置和字体大小一致 */
  width: 1em;
  height: 1em;
  vertical-align: -0.15em; /* 因icon大小被设置为和字体大小一致,而span等标签的下边缘会和字体的基线对齐,故需设置一个往下的偏移比例,来纠正视觉上的未对齐效果 */
  fill: currentColor; /* 定义元素的颜色,currentColor是一个变量,这个变量的值就表示当前元素的color值,如果当前元素未设置color值,则从父元素继承 */
  overflow: hidden;
}
</style>

Fourth, globally register the SvgIcon component just encapsulated

  1. Create a new icons folder under src, and place the svg image in the svg folder under the icons folder.
    Insert picture description here
  2. Create a new index.js file under the icons folder. The content of the file is as follows:
    index.js
import Vue from "vue";
import SvgIcon from "@/components/SvgIcon"; // svg组件

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

/**
 *require.context函数接受三个参数 
    directory {String} -读取文件的路径
    useSubdirectories {Boolean} -是否遍历文件的子目录
    regExp {RegExp} -匹配文件的正则 
 */
// 引用当前目录的svg下的所有后缀为.svg的文件
const req = require.context("./svg", false, /\.svg$/);
// 此时的req内,有三个方法,
/**
 * 
 *  1. resolve {Function}  接收一个req参数,是模块文件相对于js执行文件的路径,返回模块相对于整个工程的相对路径
    2. keys {Function} 返回匹配模块的key,一般是个相对路径,例如:./home.js
    3. id {String}  包含map对象的模块id,如第3节中的map模块
 */
// 用这个方法就能实现快速引入。下面那句 等价于const requireAll=requireContext => requireContext.keys().map(i=>requireContext(i));
const requireAll = requireContext => requireContext.keys().map(requireContext);
requireAll(req);
  1. Import the index.js file under the icons folder into main.js.
import "@/icons/index.js";

Fourth, use the just registered SvgIcon component in the component

  1. :icon-name="icon" Pass the icon name to the child component
  2. :icon-class="'my-icon'" The class name of the icon

test.vue

<template>
  <div class="test-svgicon">
    <svg-icon
      :icon-name="icon"
      :icon-class="'my-icon'"
      @click="handleClick"
    ></svg-icon>
    <el-button @click="changeIcon">点击改变icon</el-button>
  </div>
</template>
<script>
export default {
    
    
  data() {
    
    
    return {
    
    
      icon: "users" // 这里的icon的值是图标的名字,图标名最好是英文
    };
  },
  methods: {
    
    
    changeIcon() {
    
    
      this.icon = "life";
    },
    handleClick() {
    
    
      console.log("点击了图标");
    }
  }
};
</script>
<style>
.my-icon {
    
    
  font-size: 40px;
}
</style>

Insert picture description here

Insert picture description here
After changing the icon:
Insert picture description here

Guess you like

Origin blog.csdn.net/ddx2019/article/details/109048187
Recommended