vue-cli3引入svg圖標全過程以及遇到的坑


一、講原理svg-sprite,和css-sprite有點像,就是先把所有的svg圖放頁面上,但是不現實,用的時候去取。

這個時候去MDN補一下知識。Symbol這個不是es6里的那個新增的數據類型,而是SVG中的一個標簽https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element/symbol

官方說法:

symbol元素用來定義一個圖形模板對象,它可以用一個<use>元素實例化。symbol元素對圖形的作用是在同一文檔中多次使用,添加結構和語義。結構豐富的文檔可以更生動地呈現出來,類似講演稿或盲文,從而提升了可訪問性。注意,一個symbol元素本身是不呈現的。只有symbol元素的實例(亦即,一個引用了symbol的 <use>元素)才能呈現。

聯系一下我剛才說的svg-sprite你就知道了,就是我們要把我們所有svg的單個放到這個標簽里,然后再起個ID,用的時候一找這個id就出來。非常完美。原理還有更有深度的東西可以自己百度去吧。

那我們要用時候不能挨個寫標簽,挨個放進去吧,那就太麻煩了,所有用這個插件svg-sprite-loader,我們只需要准備下svg圖,然后起個好記的名字。然后svg是美工給你的,所以你只需要改名字。。為了就是這個,要不誰用他

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

接下來在vue.config.js里加這些東西。上代碼

先找到這個位置

這個位置是配置webpack額外配置的,因為vue-cli3已經幫你配置好了,但是對於這需求各種變的年代。不改是不可能的,還不如在webpack里配置呢。。吐槽一下。接下來就把下邊這些代碼放進去

const svgRule = config.module.rule('svg');
    // 清除已有的所有 loader。
    // 如果你不這樣做,接下來的 loader 會附加在該規則現有的 loader 之后。
    svgRule.uses.clear();
    svgRule
      .test(/\.svg$/)
      .include.add(path.resolve(__dirname, './src/icons/svg'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]'
      });
    const fileRule = config.module.rule('file');
    fileRule.uses.clear();
    fileRule
      .test(/\.svg$/)
      .exclude.add(path.resolve(__dirname, './src/icons/svg'))
      .end()
      .use('file-loader')
      .loader('file-loader');

你不要納悶,為啥配置這svg的規則又配置了下file,這個就是坑。

來先看一下package.json

這個開發依賴也沒有file-loader啊,配置他干嘛。。我就為了這個都哭,看着沒有,實際上有,就是這些vue/cli的某個的以來還是用的是file-loader所以你要是不配置的話,就會有兩個東西去處理你的svg,文件。他會告訴你需要你一個loader,實際上你有倆。

此時按我這個配置就可以了。為了證明有,你看看這個。。

然后自己寫個組件。,再用webpack的

require.context方法把那些svg導入進來。這個方法作用就是把所有的svg億import形式引入進來。

看代碼

先看組件

<template>
  <svg :class="svgClass" xmlns="http://www.w3.org/2000/svg">
    <use :xlink:href="iconName" xmlns:xlink="http://www.w3.org/1999/xlink" />
  </svg>
</template>

<script>
export default {
  name: 'SvgIcon',
  props: {
    iconClass: {
      type: String,
      required: true
    },
    className: {
      type: String,
      default: ''
    }
  },
  computed: {
    iconName() {
      return `#icon-${this.iconClass}`;
    },
    svgClass() {
      if (this.className) {
        return 'svg-icon ' + this.className;
      } else {
        return 'svg-icon';
      }
    }
  }
};
</script>

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

用的時候就是icon-class里的就是svg你開始的命名,別整中文啊。后邊這個class-name就是你自定義的class,要設置大小記得font-size可別width,height啥的。。那就很尷尬了

<svg-icon icon-class="copy" class-name="size"></svg-icon>

接下來就是如何引入的svg的進入頁面的

import Vue from 'vue';
import SvgIcon from '@/components/SvgIcon'; // svg組件

// register globally
Vue.component('svg-icon', SvgIcon);
const req = require.context('./svg', false, /\.svg$/);
const requireAll = requireContext => requireContext.keys().map(requireContext);
requireAll(req);

先把組件全局注冊,然后引入組件;

如果看不懂就直接百度require.context然后你就懂了。

這個時候再去main.js里引入就好了。(別忘了這一步)

import './icons'; // icon

你就可以用了,而且是頁面各個角度的用。你要看一下dom結構有沒有這個。

有你就大膽用吧,啥毛病沒有,沒有的話,是不是你svg名字給寫錯了。其他都沒錯了還是不顯示就去檢查這個webpack的配置吧和控制台的錯誤輸出。其他就只有碰到了才清楚。

現在最新版給的方法是這個(先別急着用)

1.在對應vue項目里添加插件

vue add svg-sprite

2.再執行:

npm install svgo svgo-loader --save-dev

這里開發以來會增加一個vue-cli-svg-sprite和svgo和svgo-loader

因為svgo可以整理svg的某些東西,去掉或者增加,反正是可以批量處理他們,以方便我們使用。他會給我們自動生成一個已經寫好的組件  到時候你引入這個組件就可以了。我的情況就是沒找到原因就是一直不顯示還不報錯。so,我拋棄了他,使用了上邊的方法,實際上vue-cli-svg-sprite的依賴也是svg-sprite-loader,沒准問題也是file-loader的事,應該是我的某些配置問題。如果有大神知道原因,希望你告訴我一下吧。最近沒空去探尋真理,實現了先用。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM