在vue專案中優雅的使用Svg
github demo: ofollow,noindex">github地址
閒聊背景
本文主要以 vue-cli3
搭建的專案為例,來聊一下如何在專案中更優雅的使用 svg
。
眾所周知, vue-cli3
已經推出很長一段時間了,大家可以感受一下 vue-cli3
帶來的零配置體驗。But,也相應帶來了一些弊端,就是如歸需要修改預設的 loader
時,會比較麻煩。
好了,上正題,建議看此文章之前先去看一下張旭鑫大神的 未來必熱:SVG Sprite技術介紹 ,那麼我們接下來主要使用的就是上文中提到的 svg
的 use
,先上一張 vue-cli3
搭建的專案的目錄,可以看到根目錄下只保留了 public/
以及 src/
,可以說非常乾淨,大家可以自己建立一個。

在 src/components/
下建立 SvgIcon
元件
<template> <svg :class="svgClass" aria-hidden="true"> <use :xlink:href="iconName"/> </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> 複製程式碼
在 src/
下建立一個 icons
目錄,目錄結構如下:

svg
目錄主要用於存放 svg
檔案,來看一下 index.js
的內容,功能就是把元件註冊到全域性,方便使用:
import Vue from 'vue' import SvgIcon from '@/components/SvgIcon' // svg元件 // 註冊到全域性 Vue.component('svg-icon', SvgIcon) const requireAll = requireContext => requireContext.keys().map(requireContext) const req = require.context('./svg', false, /\.svg$/) requireAll(req) 複製程式碼
當然,如果你有自己的想法或需求,可以單獨引入,無需非要註冊到全域性。
在 main.js
中引入

這一步就沒什麼好說的了,如果需要註冊到全域性,需要在入口檔案中引入。
好了,接下來是最重要的一步:
修改預設的 loader
:
大家可以去vue-cli3官網去檢視具體教程,這裡我只說需要修改的 loader
以及具體的程式碼實現。
首先需要注意的是,通過 vue-cli3
構建的專案可以初始化進行很多選擇,我構建的目錄更多的是以 *.config.js
的形式存在的。
在根目錄下建立一個名為 vue.config.js
檔案,接下來的操作都和它有關,先來看一下它完整的程式碼:
const path = require('path') function resolve (dir) { return path.join(__dirname, './', dir) } module.exports = { chainWebpack: config => { config.plugin('define').tap(args => { const argv = process.argv const icourt = argv[argv.indexOf('--icourt-mode') + 1] args[0]['process.env'].MODE = `"${icourt}"` return args }) // svg rule loader const svgRule = config.module.rule('svg') // 找到svg-loader svgRule.uses.clear() // 清除已有的loader, 如果不這樣做會新增在此loader之後 svgRule.exclude.add(/node_modules/) // 正則匹配排除node_modules目錄 svgRule // 新增svg新的loader處理 .test(/\.svg$/) .use('svg-sprite-loader') .loader('svg-sprite-loader') .options({ symbolId: 'icon-[name]', }) // 修改images loader 新增svg處理 const imagesRule = config.module.rule('images') imagesRule.exclude.add(resolve('src/icons')) config.module .rule('images') .test(/\.(png|jpe?g|gif|svg)(\?.*)?$/) }, configureWebpack: { devServer: { open: true, // https: true, proxy: { '/user': { target: 'https://devadminschool.icourt.cc', }, '/live': { target: 'https://devadminschool.icourt.cc', }, }, }, }, } 複製程式碼
大家忽略無關緊要的程式碼,重點從 svg rule loader
註釋開始,其實註釋已經比較詳細了,就是獲取預設的 loader
並進行相關的修改,主要有 svg-loader
、 images-loader
,從 vue-cli3
基礎loader 中可以找到這兩個 loader
的預設配置。
// 預設的svg loader... webpackConfig.module .rule('svg') .test(/\.(svg)(\?.*)?$/) .use('file-loader') .loader('file-loader') .options({ name: genAssetSubPath('img') }) // 預設的images loader... webpackConfig.module .rule('images') .test(/\.(png|jpe?g|gif|webp)(\?.*)?$/) .use('url-loader') .loader('url-loader') .options(genUrlLoaderOptions('img')) 複製程式碼
對比我一開始的程式碼可以看出,我把預設的 svg loader
配置中使用的 file-loader
改為了 svg-sprite-loader
,並排除了 node_modules
,把預設的 images-loader
配置添加了 svg
,並排除了 src/icons
目錄。
如何使用?
- 可以把設計大大給的svg 或者從iconfont官網下載開源的icon的svg格式,複製到
src/icons/svg
目錄下; - 點選
svg
檢視原始碼,修改fill
屬性,fill="currentColor"
,或者fill=""
,如果無此屬性,就不用管,這樣做是可以讓外部控制icon的顏色,或隨父元素的color; - 注意svg命名和SvgIcon命名一致,看一下最終使用:
src/icons/svg/go-back.svg
檔案。
總結:
以上講的比較糙,奈何文字功底是硬傷,最後附上github demo 程式碼示例: 此專案也可以當做專案初始架構,內建了vue-router、vuex等。 本文以vue-cli3建立的專案為例,之前的專案可以直接去手動修改對應的loader即可。 複製程式碼
本文是在掘金上釋出的第一篇帖子,新人入駐,還請各位前輩多關懷... 複製程式碼