vue項目中自動導入svg并愉快的使用方式
引入圖標的幾種方式
遠古時代
- 一個個小圖標png圖片引入,代碼中在一個個引用
- spirit圖片,將多個圖標放在一張png圖片上,通過background屬性顯示對應的圖標
iconfont時代
- 將整個工程用到的圖標,全部打包生成字體文件,在代碼中全局引入,只要通過標簽和class就能夠使用
缺點:
- 當新增圖標的時候,需要重新生成字體文件,當團隊開發(fā)的時候,新增圖標就顯得格外麻煩
svg時代
優(yōu)勢:
- svg可以單獨引入,不需要像iconfont一起打包
- 封裝一個全局組件,就能像iconfont一樣,傳入class名稱就能顯示對應svg圖標
注意點:svg有兼容性問題,使用的時候先跟產(chǎn)品談論清楚需求是否需要兼容ie
處理loader,對指定目錄svg文件處理
安裝loader
npm i svg-sprite-loader -D
配置vue.config.js
這里推薦一個vue指令,可以方便的查詢vue隱藏的配置文件的loader規(guī)則
vue inspect --rule svg
接下來上配置文件
找到vue.config.js 如果沒有就新建一個
const path = require("path");
// 引入path模塊
const resolve = dir => path.join(__dirname, dir);
module.exports = {
? ...,
? // 配置路徑別名
? chainWebpack: config => {
? ? // vue inspect --rule svg ?// 使用以上指令,可以獲取vue配置的loader規(guī)則
? ? // svg loader 取消src/icons目錄下的處理
? ? config.module.rule("svg").exclude.add(resolve("src/icons"));
? ? // 添加自定義loader規(guī)則 icons,只處理src/icons目錄
? ? config.module
? ? ? .rule("icons")
? ? ? .test(/\.svg$/)
? ? ? .include.add(resolve("src/icons")) // 上下文變化
? ? ? .end() // 返回上下文
? ? ? .use("svg-sprite-loader")
? ? ? .loader("svg-sprite-loader")
? ? ? .options({ symbolId: "icon-[name]" });
? },
? ...
};主要有以下幾點:
- 將svg默認規(guī)則繞開我們自定義的目錄 src/icons
- 創(chuàng)建自定義規(guī)則icons,包含我們的自定義目錄src/icons
- 配置svg使用名稱規(guī)則, icon-[文件名]
接下來使用vue inspect看下目前的配置
vue inspect --rule svg
/* 以下是我們修改后的svg loader規(guī)則 */
/* config.module.rule('svg') */
{
? test: /\.(svg)(\?.*)?$/,
? exclude: [
? ? '/Users/{UserName}/project/src/icons' /* 這個是不包含的目錄 */
? ],
? use: [
? ? /* config.module.rule('svg').use('file-loader') */
? ? {
? ? ? loader: '/Users/{UserName}/project/node_modules/file-loader/dist/cjs.js',
? ? ? options: {
? ? ? ? name: 'img/[name].[hash:8].[ext]'
? ? ? }
? ? }
? ]
}vue inspect --rule icons
// 以下是我們添加的icons loader規(guī)則
/* config.module.rule('icons') */
{
? test: /\.svg$/,
? include: [
? ? '/Users/{UserName}/project/src/icons' /* 這個是包含的目錄 */
? ],
? use: [
? ? /* config.module.rule('icons').use('svg-sprite-loader') */
? ? {
? ? ? loader: 'svg-sprite-loader',
? ? ? options: {
? ? ? ? symbolId: 'icon-[name]'
? ? ? }
? ? }
? ]
}編寫一個自定義組件
<template> ? <svg v-on="$listeners" :class="svgClass"> ? ? <use :xlink:href="iconName" rel="external nofollow" ></use> ? </svg> </template>
<script>
export default {
? name: "SvgIcon",
? props: {
? ? iconClass: {
? ? ? type: String,
? ? ? default: ""
? ? },
? ? 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>入?yún)⒂?個,iconClass(圖標的名稱)和className(自定義樣式名稱)
iconClass為src/icon下目錄的svg文件名稱
編寫一個js,實現(xiàn)svg自動化
import Vue from "vue";
import SvgIcon from "@/components/SvgIcon.vue";
const isEnv = process.env.NODE_ENV === "development";
// 自動加載 icons 目錄下的所有svg
const req = require.context("./svg", true, /\.svg$/);
const svgNameSet = new Set();
req.keys().map(url => {
? const pathSplit = url.split("/");
? const fileName = pathSplit[pathSplit.length - 1];
? isEnv && console.log(fileName);
? if (svgNameSet.has(fileName)) {
? ? isEnv && console.error("圖標名稱重復,請檢查");
? } else {
? ? svgNameSet.add(fileName);
? ? return req(url); // 可以用于異步require
? }
});
// 全局注冊SvgIcon.vue組件
Vue.component("svg-icon", SvgIcon);這個腳本主要有以下幾個內(nèi)容:
- 全局注冊SvgIcon.vue組件
- 使用require.context("./svg", true, /\.svg$/);,對src/icons目錄遞歸遍歷,獲取所有文件
- 做一遍開發(fā)環(huán)境的重復提醒(因為這邊使用的icon-[name],name是唯一的,所以當有相同文件名稱的svg,會被覆蓋)
至此就可以愉快的使用svg了
使用方法如下:
- 將svg文件復制到src/icons目錄下,比如diamond.svg
- 在vue的template中直接使用 <svg-icon iconClass="diamond"></svg-icon>
是不是很簡單,趕緊去試試吧
壓縮優(yōu)化
SVG通常會有一些冗余信息(如:fill=“red”, 還有可能導致無法修改顏色)導致影響體積,這里我們可以使用svgo-loader來進一步壓縮
// install
npm i svgo-loader -D
// vue.config.js
// 接上面svg的配置
...
.end()
.use('svgo-loader')
.loader('svgo-loader')
.end()以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
解決Vue中引入swiper,在數(shù)據(jù)渲染的時候,發(fā)生不滑動的問題
今天小編就為大家分享一篇解決Vue中引入swiper,在數(shù)據(jù)渲染的時候,發(fā)生不滑動的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09
一篇文章帶你吃透Vue生命周期(結(jié)合案例通俗易懂)
這篇文章主要給大家介紹了關于如何通過一篇文章帶你吃透Vue生命周期,文章通過結(jié)合案例更加的通俗易懂,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2022-02-02
Vue數(shù)據(jù)監(jiān)聽方法watch的使用
這篇文章主要介紹了Vue數(shù)據(jù)監(jiān)聽方法watch的使用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03
詳解Vue SSR( Vue2 + Koa2 + Webpack4)配置指南
這篇文章主要介紹了詳解Vue SSR( Vue2 + Koa2 + Webpack4)配置指南,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-11-11
Vue中的路由跳轉(zhuǎn)及傳參的多種方法小結(jié)
這篇文章主要介紹了Vue中的路由跳轉(zhuǎn)及傳參的多種方法小結(jié),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2023-11-11
vue 組件內(nèi)獲取actions的response方式
今天小編就為大家分享一篇vue 組件內(nèi)獲取actions的response方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11

