vue項(xiàng)目中自動(dòng)導(dǎo)入svg并愉快的使用方式
引入圖標(biāo)的幾種方式
遠(yuǎn)古時(shí)代
- 一個(gè)個(gè)小圖標(biāo)png圖片引入,代碼中在一個(gè)個(gè)引用
- spirit圖片,將多個(gè)圖標(biāo)放在一張png圖片上,通過background屬性顯示對(duì)應(yīng)的圖標(biāo)
iconfont時(shí)代
- 將整個(gè)工程用到的圖標(biāo),全部打包生成字體文件,在代碼中全局引入,只要通過標(biāo)簽和class就能夠使用
缺點(diǎn):
- 當(dāng)新增圖標(biāo)的時(shí)候,需要重新生成字體文件,當(dāng)團(tuán)隊(duì)開發(fā)的時(shí)候,新增圖標(biāo)就顯得格外麻煩
svg時(shí)代
優(yōu)勢(shì):
- svg可以單獨(dú)引入,不需要像iconfont一起打包
- 封裝一個(gè)全局組件,就能像iconfont一樣,傳入class名稱就能顯示對(duì)應(yīng)svg圖標(biāo)
注意點(diǎn):svg有兼容性問題,使用的時(shí)候先跟產(chǎn)品談?wù)撉宄枨笫欠裥枰嫒輎e
處理loader,對(duì)指定目錄svg文件處理
安裝loader
npm i svg-sprite-loader -D
配置vue.config.js
這里推薦一個(gè)vue指令,可以方便的查詢vue隱藏的配置文件的loader規(guī)則
vue inspect --rule svg
接下來上配置文件
找到vue.config.js 如果沒有就新建一個(gè)
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]" }); ? }, ? ... };
主要有以下幾點(diǎn):
- 將svg默認(rèn)規(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' /* 這個(gè)是不包含的目錄 */ ? ], ? 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' /* 這個(gè)是包含的目錄 */ ? ], ? use: [ ? ? /* config.module.rule('icons').use('svg-sprite-loader') */ ? ? { ? ? ? loader: 'svg-sprite-loader', ? ? ? options: { ? ? ? ? symbolId: 'icon-[name]' ? ? ? } ? ? } ? ] }
編寫一個(gè)自定義組件
<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)⒂?個(gè),iconClass(圖標(biāo)的名稱)和className(自定義樣式名稱)
iconClass為src/icon下目錄的svg文件名稱
編寫一個(gè)js,實(shí)現(xiàn)svg自動(dòng)化
import Vue from "vue"; import SvgIcon from "@/components/SvgIcon.vue"; const isEnv = process.env.NODE_ENV === "development"; // 自動(dòng)加載 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("圖標(biāo)名稱重復(fù),請(qǐng)檢查"); ? } else { ? ? svgNameSet.add(fileName); ? ? return req(url); // 可以用于異步require ? } }); // 全局注冊(cè)SvgIcon.vue組件 Vue.component("svg-icon", SvgIcon);
這個(gè)腳本主要有以下幾個(gè)內(nèi)容:
- 全局注冊(cè)SvgIcon.vue組件
- 使用require.context("./svg", true, /\.svg$/);,對(duì)src/icons目錄遞歸遍歷,獲取所有文件
- 做一遍開發(fā)環(huán)境的重復(fù)提醒(因?yàn)檫@邊使用的icon-[name],name是唯一的,所以當(dāng)有相同文件名稱的svg,會(huì)被覆蓋)
至此就可以愉快的使用svg了
使用方法如下:
- 將svg文件復(fù)制到src/icons目錄下,比如diamond.svg
- 在vue的template中直接使用 <svg-icon iconClass="diamond"></svg-icon>
是不是很簡(jiǎn)單,趕緊去試試吧
壓縮優(yōu)化
SVG通常會(huì)有一些冗余信息(如:fill=“red”, 還有可能導(dǎo)致無法修改顏色)導(dǎo)致影響體積,這里我們可以使用svgo-loader來進(jìn)一步壓縮
// install npm i svgo-loader -D // vue.config.js // 接上面svg的配置 ... .end() .use('svgo-loader') .loader('svgo-loader') .end()
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
解決Vue中引入swiper,在數(shù)據(jù)渲染的時(shí)候,發(fā)生不滑動(dòng)的問題
今天小編就為大家分享一篇解決Vue中引入swiper,在數(shù)據(jù)渲染的時(shí)候,發(fā)生不滑動(dòng)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-09-09一篇文章帶你吃透Vue生命周期(結(jié)合案例通俗易懂)
這篇文章主要給大家介紹了關(guān)于如何通過一篇文章帶你吃透Vue生命周期,文章通過結(jié)合案例更加的通俗易懂,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-02-02Vue數(shù)據(jù)監(jiān)聽方法watch的使用
這篇文章主要介紹了Vue數(shù)據(jù)監(jiān)聽方法watch的使用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-03-03詳解Vue SSR( Vue2 + Koa2 + Webpack4)配置指南
這篇文章主要介紹了詳解Vue SSR( Vue2 + Koa2 + Webpack4)配置指南,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-11-11Vue實(shí)現(xiàn)點(diǎn)擊箭頭上下移動(dòng)效果
這篇文章主要介紹了Vue實(shí)現(xiàn)點(diǎn)擊箭頭上下移動(dòng)效果,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06Vue中的路由跳轉(zhuǎn)及傳參的多種方法小結(jié)
這篇文章主要介紹了Vue中的路由跳轉(zhuǎn)及傳參的多種方法小結(jié),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2023-11-11vue 組件內(nèi)獲取actions的response方式
今天小編就為大家分享一篇vue 組件內(nèi)獲取actions的response方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-11-11