vue基于Element的动态自定义主题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_28004379/article/details/90751275

需求:实现夜间模式,白天模式或者其他自定义主题

大纲思路:

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提供的一种新换肤思路

猜你喜欢

转载自blog.csdn.net/qq_28004379/article/details/90751275
今日推荐