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

記住上次換膚效果

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

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章