在作後臺管理項目的時候,有一個功能是側邊欄可配置。可配置項有:名字、路由、圖標、權限。其中名字、路由、權限在大神的vue-element-admin中已經有很詳細的介紹了,問題就在於icon選擇配置(這個作完以後,發現不是頗有必要,由於這個項目就內部人員在用,配圖表手動輸入class名就ok了),具體方案是用element-ui的select組件自定義模板實現icon可視化選擇。css
功能實現第一步,搜索引擎大法,用baidu、google分別搜索了關鍵詞iconpicker,一大堆搜索結果,有bootstrap的,有layui的,有jquery的。
但他們的icon都是固定的庫,不能本身去增刪改。並且項目中這幾個框架都沒有引入,爲了一個功能去引入一個庫感受有點不划算(庫的OS:誰稀罕你用似的)。vue
搜索無果後,決定本身動手作一個組件,而後先列出本身想要的幾個關鍵點node
icon可維護
增刪icon簡單
圖形化選擇
爲了後期icon的維護(認真思考後感受又是一個不是必要的選項)選擇了用iconfont,能隨時添加刪除icon。
而後圖形化選擇的話,用element-ui自帶的select組件就好了
但問題關鍵在於將iconfont 引入項目
項目引入,直接將iconfont項目下載下來,放到/src/assets/font文件夾中jquery
文件卻是放到本地了,但問題是我如何知道我引入了哪些icon,以及將icon的class名輸出到一個數組裏,並在項目中可用。
手動粘貼複製卻是能夠,但下次再增刪幾個icon 還要一一對比嗎?因此條路確定不行了。
如今就是要讀去iconfont.css中的內容,並將其中的因此class提取出來git
第一個我能想到的方法就是,在vue.config.js中使用node.js的api將iconfont.css的文件內容讀取出來。github
const path = require('path') const rf = require('fs') function resolve (dir) { return path.join(__dirname, dir) } rf.readFile(resolve('src/assets/font/iconfont.css'), 'utf-8', function (err, data) { if (err) { console.log('error') return false } else { console.log(data) })
代碼確實輸出了iconfont.css中的全部內容element-ui
而後我須要對這個data進行處理,輸出一個數組bootstrap
const res = data.match(/.iconfont*.+:before/g)
提取出icon名,在輸出到一個變量中,但問題是從vue.config.js將變量輸出到哪去,才能在整個項目中使用呢?localstorage中?
並且在開發環境下可以使用node.js 在生產環境可不行。
因此我採起了一個折中的方法,將這個變量輸出到一個文件當中,而後文件中export 這個變量api
function replacer (match, p1, p2, p3, offset, string) { // p1 is nondigits, p2 digits, and p3 non-alphanumerics return p2 } rf.readFile(resolve('src/assets/font/iconfont.1.css'), 'utf-8', function (err, data) { if (err) { console.log('error') return false } else { const res = data.match(/.iconfont*.+:before/g) icondata = res.map(item => { return `'${item.replace(/(.iconfont-)(.*)(:before)/, replacer)}'` }) icondata = `export default [${icondata.toString()}]` rf.writeFile(resolve('src/utils/icon.js'), icondata, (err) => { if (err) throw err console.log('The file has been saved!') }) } })
接下來就是組件的代碼了
<template> <el-select :value="icon" filterable placeholder="請選擇" @change="handleChange"> <el-option v-for="item in icons" :key="item" :label="item" :value="item"> <span style="float: left"><i class="iconfont" :class="`iconfont-${item}`"></i></span> <span style="float: right; color: #8492a6; font-size: 13px">{{ item }}</span> </el-option> </el-select> </template> <script> import icons from '@/utils/icon' export default { props: { icon: { type: String, default: "" } }, data () { return { icons, } }, methods: { handleChange(val){ this.$emit('update:icon',val) } }, } </script> // 調用 <icon-picker :icon.sync="icon" />