vue基於Element的動態自定義主題

需求:實現夜間模式,白天模式或者其他自定義主題

大綱思路:

1.所有涉及到動態顏色修改的樣式,全部提取爲關鍵字

2.把每個單獨主題樣式最外層包裹一層class爲命名空間

3.點擊主題切換不同的class即可

方法一:

html:

      <div class="header">顯示顏色字體變化切換</div>
        <el-radio-group v-model="moreTheme" @change="changeTheme">
          <el-radio label="20a0ff">默認-20a0ff</el-radio>
          <el-radio label="fa4f52">紅色-fa4f52</el-radio>
          <el-radio label="00a597">綠色-00a597</el-radio>
          <el-radio label="FEB84A">橙色-FEB84A</el-radio>          
        </el-radio-group>
      </div>

js:

changeTheme(themeValue) {
   // 點擊單選按鈕,設置切換class
   this.changeClass(document.body, "custom-" + themeValue);
   this.moreTheme = themeValue;
},
changeClass(element, className) {
   if (!element || !className) return;
   element.className = className;
},

scss:

customeTheme文件:設置不同主題的樣式,通過判斷類實現不同樣式

// 新建一個customeTheme.scss
$background-20a0ff: #20a0ff;
$background-fa4f52: #fa4f52;
$background-00a597: #00a597;
$background-FEB84A: #FEB84A;

@mixin theme() {
   body.custom-20a0ff & {
    color: #ffffff;
    background: $background-20a0ff;
  }
  body.custom-fa4f52 & {
    color: yellowgreen;
    background: $background-fa4f52;
  }
  body.custom-00a597 & {
    color: blueviolet;
    background: $background-00a597;
  }
  body.custom-FEB84A & {
    color: palevioletred;
    background: $background-FEB84A;
  }
}

index.scss文件

@import './customeTheme.scss';
.header{
  width: 100%;
  height: 100px;
  @include theme()
}

然後將Index.scss引入到main.js文件中

import "@/assets/mytheme/index.scss"; // 換膚

運行效果如下:

demo1

當然也不用設置類名,可以設置屬性,【還是通過sass判斷然後賦上不同樣式】

js:

    changeTheme(themeValue) {
      // 設置屬性custome,然後切換修改樣式
      window.document.documentElement.setAttribute('custome',themeValue);
    },

customeTheme文件就不是判類了,而是判斷屬性值

// 新建一個customeTheme.scss
$background-20a0ff: #20a0ff;
$background-fa4f52: #fa4f52;
$background-00a597: #00a597;
$background-FEB84A: #FEB84A;

@mixin theme() {

  [custome = "20a0ff"] & {
    color: #ffffff;
    background: $background-20a0ff;
  }
  [custome = "fa4f52"] & {
    color: yellowgreen;
    background: $background-fa4f52;
  }
  [custome = "00a597"] & {
    color: blueviolet;
    background: $background-00a597;
  }
  [custome = "FEB84A"] & {
    color: palevioletred;
    background: $background-FEB84A;
  }
}

運行效果是一樣的。

方法二:修改element整體自定義主題

1.首先安裝一下element的主題依賴

npm i element-ui -S
npm i sass-loader node-sass -D
npm i element-theme -g
npm i element-theme-chalk -D

2.初始化變量文件

et -i

//可以自定義變量文件,默認爲element-variables.scss

3. 編輯主題

et

編譯完成之後會在主目錄下生成theme的文件,【習慣拖動文件到src/assets下】

4.引入剛剛編譯之後的index.css到main.js中

import './assets/theme/index.css';

基本上準備工作了做完了,需要給主題樣式一個獨立的命名空間。我們可以採用gulp的css-wrap

5.安裝gulp-css-wrap

//1.安裝gulp:
npm install  gulp

//2.安裝gulp-clean-css
npm install gulp-clean-css

//3.安裝gulp-css-wrap
npm install gulp-css-wrap

6.在跟目錄下新建一個gulpfile.js文件

var path = require('path')
var gulp = require('gulp')
var cleanCSS = require('gulp-clean-css');
var cssWrap = require('gulp-css-wrap');
// 設置不同的主題命名空間
var customThemeName='.custom-FEB84A'

gulp.task('css-wrap', function() {
  return gulp.src( path.resolve('./src/assets/theme/index.css'))
    .pipe(cssWrap({selector:customThemeName}))/* 添加的命名空間 */
    .pipe(cleanCSS())
    .pipe(gulp.dest('./src/assets/gulptheme/FEB84A'));/* 存放FEB84A文件下目錄 */
});
// index.css需要fonts裏面的依賴
gulp.task('move-font', function() {
  return gulp.src(['./src/assets/theme/fonts/**']).pipe(gulp.dest('./src/assets/gulptheme/FEB84A/fonts'));
});

溫馨提示:修改theme/index.css的樣式爲我們需要的樣式之後再進行gulp css-wrap,保存主題到指定路徑

運行

會看見生成的文件在我們制定的目錄下

7 引入我們的主題樣式在main.js中

import "@/assets/gulptheme/fa4f52/index.css"; // 換膚版本fa4f52 css
import "@/assets/gulptheme/20a0ff/index.css"; // 換膚版本20a0ff css
import "@/assets/gulptheme/00a597/index.css"; // 換膚版本00a597 css
import "@/assets/gulptheme/FEB84A/index.css"; // 換膚版本FEB84A css

8.剩下的思路也是切換按鈕讓class類進行修改,和方法一一樣。可以稍微調一下細節,比如默認選擇是一個主題色,通過storage判斷當前是哪個主題,如果沒有采用默認值

export default {
  data() {
    return {
      moreTheme: "20a0ff",
    };
  },
  mounted() {
    let themeClassName = "";
    // 獲取localStorage值是否設置
    let localTheme = localStorage.getItem("customTheme");
    // 有,採用當前主題,否則採用默認主題
    themeClassName = localTheme ? localTheme : "20a0ff";
    this.changeClass(document.body, "custom-" + themeClassName);
    this.moreTheme = themeClassName;
  },
  methods: {
    changeClass(element, className) {
      if (!element || !className) return;
      element.className = className;
    },
    changeTheme(themeValue) {
      this.changeClass(document.body, "custom-" + themeValue);
      this.moreTheme = themeValue;
      localStorage.setItem("customTheme", themeValue);
    }
  }
};

運行效果:

自定義主圖

 

做完之後發現,這種有個明顯的弊端,就是隻能設置少量主題。如果需求的主題是點擊某個顏色主題就是哪個顏色,就完全不適合了。可以研究一下下面幾個參考。

element採用比較簡單粗暴的做法:【a:把顏色有關的全部設置成關鍵字,b:通過用戶選的顏色值生成一些列顏色值,c:把生成的值替換之前關鍵字的值e:頁面添加style標籤,把樣式加進去】

element實現自定義換膚

一些自定義換膚的參考

element2.0提供的一種新換膚思路

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