使用vue + less 實現簡單換膚功能
做的換膚效果比較簡單,只是頂部導航背景色的改變。下面是效果圖。
首先,先說一下我最初的思路。
我最初的想法是使用less定義變數,然後通過js來切換變數,通過切換的變數來達到換膚的效果。
我先新建了一個 theme.less檔案,程式碼如下:
@theme:@themea;
@themea:pink;
@themeb:blue;
@themec:gray;
如我最開始的想法,應該是通過點選事件來改變變數 @theme 的值。
我用了element-ui這個框架,所以我的下拉選單的程式碼也不復雜:
<el-dropdown class= "colorBtn " trigger="click" @command="changeColor">
<span class="el-dropdown-link " >換膚</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="a" @click="change_type(a)">夢幻粉</el-dropdown-item>
<el-dropdown-item command="b" @click="change_type(b)" >天空藍</el-dropdown-item>
<el-dropdown-item command="c" @click="change_type(c)">霧霾灰</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
點選事件的回撥事件繫結在command事件,我定義了一個changeColor的方法
changeColor(command){
console.log(command);//能獲取到當前點選的元素的command
}
於是,問題來了,我怎麼通過點選事件來改變@theme的值呢?我陷入了沉(搜)思(索)……
終於找到了一個迂迴解決問題的方法,其實一開始的想法也沒有問題,但是需要再包裝一層。怎麼包裝呢?我們雖然暫時控制不了變數值,但是我們可以控制元素的類名。
我們可以將換膚的部分抽出來用less函式來表示,將theme.less程式碼改成下面程式碼
其中 @backcolor是背景色,@fcolor是字型顏色
.theme(@backcolor:#EEA2AD,@fcolor:#fff) {
.header {
color: @fcolor;
background: @backcolor;
width: 100%;
height: 2rem;
position: relative;
h4 {
width: 100%;
text-align: center;
line-height: 2rem;
font-size: 1rem;
}
.go-back {
width: 2rem;
height: 2rem;
text-align: center;
color: #fff;
font-size: 0.8rem;
float: left;
line-height: 2rem;
margin-left: 1rem;
position: absolute;
left: 0;
top: 0;
}
.header-cont {
width: 100%;
text-align: center;
line-height: 2rem;
font-size: 1rem;
color: #fff;
}
.colorBtn {
width: 2rem;
height: 2rem;
text-align: center;
color: #fff;
font-size: 0.8rem;
line-height: 2rem;
margin-right: 1rem;
position: absolute;
top: 0;
right: 0;
}
}
}
新建一個color.less,設定幾種不同的面板樣式。這裡不同的面板樣式,我用themea,themeb,themec….來表示,對應元件中的command值。當我點選粉色的時候,呼叫相應的函式給元素新增相對應的類名。不要忘記引用 theme.less
@import url('./theme.less');
.themea{
.theme();//預設的樣式
}
.themeb{
.theme(blue,#fff);
}
.themec{
.theme(#111,#999);
}
當點選換膚的下拉選單時,呼叫的changeColor方法需要給元素新增不同的類名,當然color.less檔案記得引用。
changeColor(command){
console.log(command);
document.getElementById('app').className ='theme'+command ;
}
在這一塊的時候,剛開始我也遇到一個問題,就是我剛開始只將這個頁面的樣式單獨抽了出來,所以其他元件的頭部樣式並沒有改變。我的第一個想法竟然是使用cookie,額,後來想著既然是單頁面,那我將樣式繫結在比較頂層的元素上,是不是可以?
結果,顯而易見!!!
如果要記住上一次換的面板,我使用的是localStorage,將每次點選換膚的主題記錄下來,然後再頁面渲染之前判斷是否有這個主題就可以了。效果如下
接下來,還有一系列單頁面部落格的製作,敬請關注。
當然,如果有大牛看到,希望指點一二。