阿里图标库iconfont,svg图标的symbol引用,结合svg-sprite-loader 使用 (优雅的使用svg)

svg-sprite-loader 的作用: 将加载的 svg 图片拼接成 雪碧图,放到页面中,方便其它地方通 复用
(可以理解为 把SVG转成了HTML的symbol标签,引入优雅,流畅)

一、安装 svg-sprite-loader

yarn add svg-sprite-loader -D

二、配置webpack

vue.config.js文件

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();
  }
};

三、封装 SvgIcon组件

<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>

四、全局注册刚刚封装的 SvgIcon组件

  1. 在src下新建一个icons的文件夹,并将svg图放在icons文件夹下的svg文件夹内。
    在这里插入图片描述
  2. 在icons文件夹下新建index.js文件,文件内容如下:
    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. 在main.js中引入icons文件夹下的index.js文件。
import "@/icons/index.js";

四、在组件中使用刚刚注册的SvgIcon组件

  1. :icon-name="icon" 给子组件传递图标名
  2. :icon-class="'my-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>

在这里插入图片描述

在这里插入图片描述
改变图标后:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/ddx2019/article/details/109048187