我能想到的主題切換方式無(wú)非兩種:
前一種方式在花褲衩同學(xué)的vue-element-admin中有具體的實(shí)現(xiàn),項(xiàng)目主頁(yè):https://github.com/PanJiaChen/vue-element-admin
他是先將element自己提供的變量文件修改后生成新的css,然后將該css用gulp進(jìn)行二次編輯增加命名空間,然后引入。也就是說(shuō)他只是修改了UI框架的主題,并沒有修改自己寫的樣式主題。
第二種方式則是element自己生成一個(gè)sass變量文件,執(zhí)行命令行后生成新主題,然后讓開發(fā)者自己導(dǎo)入。
以上兩種其實(shí)都并沒有實(shí)現(xiàn)項(xiàng)目本身自定義樣式的主題切換,所以就產(chǎn)生了很多的問(wèn)題。但仔細(xì)分析一下,其實(shí)我們只要將自己寫的css樣式也如同element官方那樣打包一遍,然后動(dòng)態(tài)引入就好了嘛。當(dāng)然也可能是我傻,沒想到還有其他方法。
介于以上總結(jié),項(xiàng)目中設(shè)計(jì)的主題加載和切換方式大致流程如下:
1. 頁(yè)面中僅引入基本樣式
2. 頁(yè)面初始化完成,動(dòng)態(tài)加載主題文件
3. 用戶切換主題:判斷主題文件是否已經(jīng)存在,存在則不操作;不存在則清空所有的主題文件,然后動(dòng)態(tài)加載對(duì)應(yīng)的主題文件。
當(dāng)前主題編寫參考了Element的主題切換方式,通過(guò)sass進(jìn)行變量修改。
# 復(fù)制基礎(chǔ)變量文件 (src/assets/css/theme/default.scss),重命名為 blue.scss 并修改內(nèi)部變量# 在 src/assets/css 目錄中創(chuàng)建新的主題入口文件 theme-blue.scss,并做如下引入// 引入新主題變量文件@import './theme/blue'// 引入默認(rèn)主題@import './theme-default'
如此簡(jiǎn)單的便可以完成主題創(chuàng)建。前文說(shuō)過(guò)我們需要?jiǎng)討B(tài)引入文件,而動(dòng)態(tài)引入我采用的是js讀取文件路徑并加載的形式,也就意味著該文件必須存在實(shí)際的物理地址,所以你需要先對(duì)項(xiàng)目進(jìn)行打包,生成對(duì)應(yīng)的靜態(tài)的css文件,而不是scss文件。為了達(dá)成這個(gè)目的我們還需要對(duì)webpack進(jìn)行設(shè)置。沿著這個(gè)思路我們還需要做以下工作。
在webpack.prod.conf.js中對(duì)入口變量做出修改,注意是prod.js
// 增加新的入口,并賦予文件名和路徑entry: { 'theme-default': './src/assets/style/theme-default.scss'}// 對(duì)HtmlWebpackPlugin插件增加忽略chunk設(shè)置,防止該chunk被加入到生成后的html中new HtmlWebpackPlugin({ excludeChunks: ['theme-default']})
配置好新的入口后,我們對(duì)項(xiàng)目進(jìn)行打包,等待編譯完成。當(dāng)打包結(jié)束后我們應(yīng)該能夠看到在dist\static\css
下有新增的theme文件,這個(gè)文件就是我們的主題文件了。接下來(lái)則是為主題切換做基礎(chǔ)。我們需要把生成的文件路徑提供給js。但是要意識(shí)到,該文件在開發(fā)時(shí)是沒有的,只有在打包完成后才有,所以我們需要另一個(gè)操作:改寫打包文件。
在打包文件生成后,我們需要利用node循環(huán)讀取dist\static\css
下的所有文件,并把所有的theme文件路徑輸出到html中,當(dāng)然你也可以輸出到公共js中,比如app.js。這里具體的實(shí)現(xiàn)方法請(qǐng)看build\themeExtract.js
寫完文件后我們只需要執(zhí)行它就可以了。當(dāng)然了,把它直接和 npm run build
綁定到一起不是更好嗎?所以在 package.json
中做如下修改即可
"scripts": { "dev": "node build/dev-server.js", "start": "node build/dev-server.js", // &&代表順序執(zhí)行 "build": "node build/build.js && node build/themeExtract.js"}
執(zhí)行后,我們?cè)倏纯创虬蟮膆tml文件,在head部分能看到一個(gè)全局的變量themeURL,里面就是我們需要的所有的主題文件路徑了。
在本篇文章發(fā)表時(shí),本項(xiàng)目master分支并沒有以上說(shuō)的所有信息,想看的請(qǐng)clone本項(xiàng)目然后切換到dev分支
在上個(gè)步驟中我們已經(jīng)有了全局變量themeURL,那么只需要對(duì)主題文件進(jìn)行匹配即可。當(dāng)更換主題時(shí),我們先查找已經(jīng)加載的主題,如果沒有則直接插入主題文件,如果有則清空所有主題文件,然后再插入。至于動(dòng)態(tài)插入文件的方法,項(xiàng)目中已對(duì)該方法進(jìn)行封裝,可在 src\util\changeTheme.js
中查看。
# 使用主題切換的方法示例,需要保證changeTheme()中的參數(shù)與主題文件名保持一致@import changeTheme from '@/util/changeTheme'export default { loadTheme(theme){ changeTheme(theme) }}
因?yàn)橹黝}文件是打包后才生成的,所以在開發(fā)環(huán)境中,主題切換并不好用,只能通過(guò)手動(dòng)修改sass主題文件的方式來(lái)做切換了,這也是目前該方案最大的問(wèn)題。
至于調(diào)試動(dòng)態(tài)載入主題js是否成功…..唔,你先打包一份,然后把打包后的多出來(lái)的變量復(fù)制到 src\index.html
中就可以了嘛…
這種切換方式能夠最大程度上避免CSS污染,頁(yè)面也更加干凈,不會(huì)產(chǎn)生多余的文件。
如果使用偷懶的方法,將所有自己寫的樣式都放到主題中(比如我),那么后期維護(hù)也異常的簡(jiǎn)單,改改變量值就可以了嘛。
如果使用繁瑣的方法,抽出所有樣式中的主題部分(如背景色、文字、顏色、圖片等),也能極大減少主題文件的大小,就是后期維護(hù)的時(shí)候會(huì)同時(shí)看兩個(gè)文件才能知道這里真正的樣式是什么,而且在編輯時(shí)容易丟東西。
當(dāng)前最大的問(wèn)題就是在開發(fā)環(huán)境中無(wú)法調(diào)試,以及在打包生成后的文件中雖然生成了css,但也對(duì)應(yīng)的生成了一份空的js,很蛋痛。如果有解決方法的話還請(qǐng)留言,謝謝。
當(dāng)前源碼地址:https://github.com/harsima/vue-backend
請(qǐng)注意,該源碼會(huì)不斷更新(因?yàn)楣ぷ骱苊Σ荒鼙WC定期更新)。源碼涉及到的東西有超出本篇教程的部分,請(qǐng)酌情閱讀。同時(shí)請(qǐng)暫時(shí)不要使用release版本,在解決該版本下的大部分BUG及目錄優(yōu)化后,會(huì)放出相對(duì)完整的release版本。更多問(wèn)題可以提交issue。
聯(lián)系客服