zoukankan      html  css  js  c++  java
  • Vue3 使用 svg-sprite-loader 实现 svg 图标按需加载

    前面文章有讲到 svg 图标按需加载的优势以及 Vue 如何使用 vue-svg-icon 实现 svg 图标按需载入
    今天来学习一下使用 svg-sprite-loader 在 Vue3 项目中实现图标按需加载

    1、将 email.svg 文件导入项目

    <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
      <path d="M4 4H20C21.1 4 22 4.9 22 6V18C22 19.1 21.1 20 20 20H4C2.9 20 2 19.1 2 18V6C2 4.9 2.9 4 4 4Z" stroke="currentColor"
        stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
      <path d="M22 6L12 13L2 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
    </svg>
    

    这里将 svg 图标中对应的图标颜色值改为字符串 currentColor,方便使用时控制图标实时颜色
    将图标放在特定文件夹下,这里以 @/assets/svg 中导入的 svg 为例

    2、安装 svg-sprite-loader

    npm i svg-sprite-loader
    

    3、配置 vue.config.js

    const path = require("path");
    
    module.exports = {
      // 配置使用stylus全局变量
      chainWebpack: config => {
        const svgRule = config.module.rule("svg");
        svgRule.uses.clear();
        svgRule
          .use("svg-sprite-loader")
          .loader("svg-sprite-loader")
          .options({
            symbolId: "icon-[name]"
          })
          .end();
      }
    };
    

    4、新建 SvgIcon.vue 文件,这里可传入 name 属性控制图标类型,传入 size 属性控制图标大小,传入 color 属性控制图标颜色

    <template>
      <svg
        class="svg-icon"
        :style="{
           props.size + 'px',
          height: props.size + 'px',
          color: props.color
        }"
        @mousedown="clickIcon"
      >
        <use :xlink:href="`#icon-${props.name}`" :fill="props.color" />
      </svg>
    </template>
    
    <script lang="ts">
    import { defineComponent } from "vue";
    
    export default defineComponent({
      name: "SvgIcon",
      props: {
        name: {
          type: String,
          required: true,
          default: "email"
        },
        size: {
          type: Number,
          default: 32
        },
        color: {
          type: String,
          default: "#000"
        }
      },
      setup(props) {
        return {
          props
        };
      }
    });
    </script>
    

    5、在 src 目录下新建 plugin.ts

    import SvgIcon from "@/pages/components/SvgIcon.vue";
    
    const componentPlugin: any = {
      install: function(vue: any, options: any) {
        if (
          options &&
          options.imports &&
          Array.isArray(options.imports) &&
          options.imports.length > 0
        ) {
          // 按需引入图标
          const { imports } = options;
          imports.forEach((name: any) => {
            require(`@/assets/svg/${name}.svg`);
          });
        } else {
          // 全量引入图标
          const ctx = require.context("@/assets/svg", false, /.svg$/);
          ctx.keys().forEach(path => {
            const temp = path.match(/./([A-Za-z0-9-_]+).svg$/);
            if (!temp) return;
            const name = temp[1];
            require(`@/assets/svg/${name}.svg`);
          });
        }
        vue.component(SvgIcon.name, SvgIcon);
      }
    };
    export default componentPlugin;
    

    6、在 main.js(或 main.ts)中引入上面的 plugin 文件

    import plugin from "./plugin";
    
    createApp(App)
      .use(plugin, {
        imports: []
      })
    

    7、图标组件的使用

    <SvgIcon name="email" :size="24" color="#777" />
    
  • 相关阅读:
    Anagram
    HDU 1205 吃糖果(鸽巢原理)
    Codeforces 1243D 0-1 MST(补图的连通图数量)
    Codeforces 1243C Tile Painting(素数)
    Codeforces 1243B2 Character Swap (Hard Version)
    Codeforces 1243B1 Character Swap (Easy Version)
    Codeforces 1243A Maximum Square
    Codeforces 1272E Nearest Opposite Parity(BFS)
    Codeforces 1272D Remove One Element
    Codeforces 1272C Yet Another Broken Keyboard
  • 原文地址:https://www.cnblogs.com/Leophen/p/14157256.html
Copyright © 2011-2022 走看看