Vue、Element自定义主题的实现

4,079 阅读3分钟

1.安装 Element 及 sass-loader,node-sass

安装 Element

npm i element-ui -S

安装 sass

npm i sass-loader node-sass -d

2.引入 Element

完整引入

import Vue from 'vue';
import ElementUI from 'element-ui';
// 注释掉样式文件
// import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';

Vue.use(ElementUI);

new Vue({
  el: '#app',
  render: h => h(App)
});

3.安装自定义主题工具

npm i element-theme -g

然后安装chalk主题

npm i element-theme-chalk -D

初始化变量文件

主题生成工具安装成功后,如果全局安装可以在命令行里通过 et 调用工具,如果安装在当前目录下,需要通过 node_modules/.bin/et 访问到命令。执行 -i 初始化变量文件。默认输出到 element-variables.scss,当然你可以传参数指定文件输出目录。

et -i [可以自定义变量文件]

> ✔ Generator variables file

如果使用默认配置,执行后当前目录会有一个 element-variables.scss 文件。内部包含了主题所用到的所有变量,它们使用 SCSS 的格式定义。大致结构如下:

/* Element Chalk Variables */

// Special comment for theme configurator
// type|skipAutoTranslation|Category|Order
// skipAutoTranslation 1

/* Transition
-------------------------- */
$--all-transition: all .3s cubic-bezier(.645,.045,.355,1) !default;
$--fade-transition: opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) !default;
$--fade-linear-transition: opacity 200ms linear !default;
$--md-fade-transition: transform 300ms cubic-bezier(0.23, 1, 0.32, 1), opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) !default;
$--border-transition-base: border-color .2s cubic-bezier(.645,.045,.355,1) !default;
$--color-transition-base: color .2s cubic-bezier(.645,.045,.355,1) !default;

/* Color
-------------------------- */
/// color|1|Brand Color|0
/*
default #14B1FA
redWhite #D51F43
*/
$--color-primary: #D51F43 !default;
/// color|1|Background Color|4
$--color-white: #FFFFFF !default;
/// color|1|Background Color|4
$--color-black: #000000 !default;
$--color-primary-light-1: mix($--color-white, $--color-primary, 10%) !default; /* 53a8ff */
$--color-primary-light-2: mix($--color-white, $--color-primary, 20%) !default; /* 66b1ff */
$--color-primary-light-3: mix($--color-white, $--color-primary, 30%) !default; /* 79bbff */
$--color-primary-light-4: mix($--color-white, $--color-primary, 40%) !default; /* 8cc5ff */
$--color-primary-light-5: mix($--color-white, $--color-primary, 50%) !default; /* a0cfff */
$--color-primary-light-6: mix($--color-white, $--color-primary, 60%) !default; /* b3d8ff */
$--color-primary-light-7: mix($--color-white, $--color-primary, 70%) !default; /* c6e2ff */
$--color-primary-light-8: mix($--color-white, $--color-primary, 80%) !default; /* d9ecff */
$--color-primary-light-9: mix($--color-white, $--color-primary, 90%) !default; /* ecf5ff */
/// color|1|Functional Color|1
$--color-success: #67C23A !default;
/// color|1|Functional Color|1
$--color-warning: #E6A23C !default;
/// color|1|Functional Color|1
$--color-danger: #F56C6C !default;
/// color|1|Functional Color|1
$--color-info: #909399 !default;

修改变量

直接编辑 element-variables.scss 文件,例如修改主题色为所需色值。

$--color-primary: #D51F43 !default;

编译主题

保存文件后,到命令行里执行 et 编译主题,如果你想启用 watch 模式,实时编译主题,增加 -w 参数;如果你在初始化时指定了自定义变量文件,则需要增加 -c 参数,并带上你的变量文件名。默认情况下编译的主题目录是放在 ./theme 下,你可以通过 -o 参数指定打包目录。

et

> ✔ build theme font
> ✔ build element theme

4.搭建 gulp 环境

安装 gulp

npm install gulp -g

安装 gulp-clean-css

npm install gulp-clean-css -d

安装 gulp-css-wrap

npm install gulp-css-wrap -d

在项目根目录下创建 gulpfile.js 的文件

// gulpfile.js
var path = require('path')
var gulp = require('gulp')
var cleanCSS = require('gulp-clean-css')
var cssWrap = require('gulp-css-wrap')

/*
default
*/
var themeName = 'default' // 主题变量

gulp.task('css-wrap', function() {
  return gulp.src(path.resolve('./theme/index.css'))
  /* 找需要添加命名空间的css文件,支持正则表达式 */
  .pipe(cssWrap({
    selector: '.custom-' + themeName /* 添加的命名空间 */
  }))
  .pipe(cleanCSS())
  .pipe(gulp.dest('src/assets/css/theme/' + themeName)) /* 存放的目录 */
})

执行gulp输出

gulp css-wrap

会在指定目录下生成文件:

5.在 App.vue 中引入

import '@/assets/css/theme/default/index.css'; // default主题

6.动态主题切换

修改element-variables.scss文件编译后,用gulp-css-wrap生成新的主题文件,在App.vue中全部引入

通过js动态给body添加/修改类名既可做到动态主题切换

// 换肤加class函数
Vue.prototype.toggleClass = function(element, className) {
  if (!element || !className) {
    return
  }
  element.className = className;
}
// 主题切换
themeSwitch() {
  let themeName = default
  this.toggleClass(document.body, "custom-" + themeName)
}

参考链接:

vue-基于elementui换肤[自定义主题]

gulp-css-wrap工具的使用——[批量为css文件扩展命名空间]