1. 程式人生 > >使用vue + less 實現簡單換膚功能

使用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,將每次點選換膚的主題記錄下來,然後再頁面渲染之前判斷是否有這個主題就可以了。效果如下

記住上次換膚效果

接下來,還有一系列單頁面部落格的製作,敬請關注。

當然,如果有大牛看到,希望指點一二。