- 首先我們得有圖標
- 這里我們從網上下載svg文件或者UI給你導出svg文件
- 我們在src 文件下新建一個放置svg 文件 的文件夾 @/src/icons.將所有 icon 放在這個文件夾下。

- 創建 icon-component 組件

-
<template> <svg :class="svgClass" aria-hidden="true" :color="svgColor" > <use :xlink:href="iconName" /> </svg> </template> <script lang="ts"> import { Component, Vue, Prop } from 'vue-property-decorator'; @Component({ components: {} }) export default class SvgIcon extends Vue { @Prop({ default: null, type: String }) iconClass!: String; @Prop({ default: '', type: String }) className!: String; @Prop({ default: null, type: String }) svgColor!: String; get iconName() { return `#icon-${this.iconClass}`; } get svgClass() { if (this.className) return `svg-icon ${this.className}`; return 'svg-icon'; } } </script> <style scoped> .svg-icon { width: 2em; height: 2em; vertical-align: -0.15em; fill: currentColor; overflow: hidden; } </style>
- 在icons 文件夾放一個index.js 這個js 的作用是引入 icon組件並全局注冊 並實現 自動引入
@/src/icons下面所有的圖標了- 之后我們就要使用到 webpack 的 require.context。很多人對於
require.context可能比較陌生,直白的解釋就是-
require.context("./test", false, /.test.js$/); 這行代碼就會去 test 文件夾(不包含子目錄)下面的找所有文件名以
.test.js結尾的文件能被 require 的文件。 更直白的說就是 我們可以通過正則匹配引入相應的文件模塊。
-
-
import Vue from 'vue'; import IconSvg from '@/components/IconSvg/IconSvg.vue'; // 全局注冊icon-svg Vue.component('icon-svg', IconSvg); // requires and returns all modules that match const requireAll = requireContext => requireContext.keys().map(requireContext); // import all svg const req = require.context('./svg', true, /\.svg$/); requireAll(req);
- 之后我們就要使用到 webpack 的 require.context。很多人對於
- svg-sprite-loader 依賴 install
- 它是一個 webpack loader ,可以將多個 svg 打包成
svg-sprite。 - 我們發現
vue-cli默認情況下會使用url-loader對svg進行處理,會將它放在/img目錄下,所以這時候我們引入svg-sprite-loader會引發一些沖突。 -
//默認`vue-cli` 對svg做的處理,正則匹配后綴名為.svg的文件,匹配成功之后使用 url-loader 進行處理。 { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('img/[name].[hash:7].[ext]') } }
- 它是一個 webpack loader ,可以將多個 svg 打包成
-
- 解決方案有兩種,最簡單的就是你可以將 test 的 svg 去掉,這樣就不會對svg做處理了,當然這樣做是很不友善的。
- 你不能保證你所有的 svg 都是用來當做 icon的,有些真的可能只是用來當做圖片資源的。
- 不能確保你使用的一些第三方類庫會使用到 svg。
- 所以最安全合理的做法是使用 webpack 的 exclude 和 include ,讓
svg-sprite-loader只處理你指定文件夾下面的 svg,url-loaer只處理除此文件夾之外的所以 svg,這樣就完美解決了之前沖突的問題。 代碼如下 
- 這只是cli2 的配置, cli3 配置都在vue.config.js 里面 詳情參看文檔 webpack相關 | vue-cli3
- 這里吧我自己寫的給貼出來
-
module.exports = { lintOnSave: true, baseUrl: './', productionSourceMap: process.env.NODE_ENV !== 'production', chainWebpack: (config) => { config.resolve.alias.set('@images', resolve('./src/assets/images')); config.resolve.alias.set('@svg', resolve('./src/icons/svg')); config.module.rules.delete('svg'); // 重點:刪除默認配置中處理svg, config.module .rule('svg-sprite-loader') .test(/\.svg$/) .include .add(resolve('src/icons/svg')) // 處理svg目錄 .end() .use('svg-sprite-loader') .loader('svg-sprite-loader') .options({ symbolId: 'icon-[name]', }); }, ......
- 解決方案有兩種,最簡單的就是你可以將 test 的 svg 去掉,這樣就不會對svg做處理了,當然這樣做是很不友善的。
這樣配置好了,開始使用了.

<icon-svg icon-class="send" className="icon"
/>
效果
參考鏈接: 手摸手,帶你優雅的使用 icon
更詳細的 可以去看看上面鏈接,大神帶你飛
