1. 程式人生 > >封裝全域性icon元件 svg (仿造element-ui原始碼)

封裝全域性icon元件 svg (仿造element-ui原始碼)

一、引入  svg-sprite-loader 外掛

npm install svg-sprite-loader --save-dev

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 的 exclude和 include,讓svg-sprite-loader只處理你指定資料夾下面的 svg,url-loaer只處理除此資料夾之外的所以 svg,這樣就完美解決了之前衝突的問題。對配置檔案進行以下修改:

{
  test: /\.svg$/,
  loader: 'svg-sprite-loader',
  include:[resolve(
'src/assets/icons')], options: { symbolId: 'icon-[name]', name: utils.assetsPath('img/[name].[hash:7].[ext]') } }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', exclude:[resolve('src/assets/icons')], options: { limit: 10000, name: utils.assetsPath('img/[name].[hash:7].[ext]') } },

二、建立全域性元件

建立vue-cli專案,在src/components下建立icon-svg.vue檔案。

<template>
  <svg class="svg-icon" aria-hidden="true">
    <use :xlink:href="iconName"></use>
  </svg>
</template>

<script>
export default {
  name: 'icon-svg',
  props: {
    iconClass: {
      type: String,
      required: true
    }
  },
  computed: {
    iconName() {
      return `#icon-${this.iconClass}` // 與配置檔案的配置格式一致
    }
  }
}
</script>

<style>
.svg-icon {
  width: 50px;
  height: 50px;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}
</style>

在入口檔案全域性註冊元件

//引入svg元件
import IconSvg from '@/components/icon-svg'

//全域性註冊icon-svg
Vue.component('icon-svg', IconSvg)

操作完成之後就可以在vue檔案中使用svg圖示了:

import '@/assets/icons/attach_excel.svg'; //引入圖示

直接使用
<svg><use xlink:href="#icon-attach_excel"/></svg>

全域性元件形式使用
<icon-svg iconClass="attach_excel"></icon-svg>

三、新增自動匯入svg檔案

首先我們建立一個專門放置圖示 icon 的資料夾如:@/src/icons,將所有 icon 放在這個資料夾下。

之後我們就要使用到 webpack 的 require.context:

require.context("./test", false, /.test.js$/);
這行程式碼就會去 test 資料夾(不包含子目錄)下面的找所有檔名以 .test.js 結尾的檔案能被 require 的檔案。
即我們可以通過正則匹配引入相應的檔案模組。

require.context有三個引數:

  • directory:說明需要檢索的目錄
  • useSubdirectories:是否檢索子目錄
  • regExp: 匹配檔案的正則表示式

接下來可以在入口檔案這樣寫,來自動引入 @/src/icons 下面所有的圖示:

const requireAll = requireContext => requireContext.keys().map(requireContext)
const req = require.context('@/assets/icons', true, /\.svg$/)
requireAll(req)

vue檔案直接使用:

<icon-svg iconClass="attach_excel"></icon-svg>

 

 

參考網址:https://segmentfault.com/a/1190000012213278