.title { color: pink; } //命名空间后就变成 .theme.title { color: pink; }那么多的样式,难道要一个一个给样式新增命名空间?作为程序员,当然不能用那么笨的方法。我们可以借助构建工具 gulp,帮我们实现命名空间。
//1.安装gulp npm install gulp //2.安装gulp-clean-css npm install gulp-clean-css //3.安装gulp-css-wrap npm install gulp-css-wrap根目录新建一个gulpfile.js文件
//堆代码 duidaima.com //引入path var path = require("path") //引入gulp var gulp = require("gulp") //引入gulp-clean-css var cleanCSS = require("gulp-clean-css") //引入gulp-css-wrap var cssWrap = require("gulp-css-wrap") //创建一个命令(任务) normal-theme 执行此命令,会进行如下操作 gulp.task("normal-theme", function() { //导入文件 return gulp.src(path.resolve("./src/themes/normal/index.css")) /* 找需要添加命名空间的css文件,支持正则表达式 */ .pipe(cssWrap({ selector: ".bu-normal" /* 添加的命名空间 */ })) .pipe(cleanCSS()) .pipe(gulp.dest("./src/styles/themes/normal")) /* 存放的目录 */ }) //把字体文件也导入 gulp.task("normal-theme-font", function() { return gulp.src(["./src/themes/normal/fonts/**"]).pipe(gulp.dest("./src/styles/themes/normal/fonts")) }) //创建一个命令(任务) normal-theme 执行此命令,会进行如下操作 gulp.task("night-theme", function() { //导入文件 return gulp.src(path.resolve("./src/themes/night/index.css")) /* 找需要添加命名空间的css文件,支持正则表达式 */ .pipe(cssWrap({ selector: ".bu-night" /* 添加的命名空间 */ })) .pipe(cleanCSS()) .pipe(gulp.dest("./src/styles/themes/night")) /* 存放的目录 */ }) //把字体文件也导入 gulp.task("night-theme-font", function() { return gulp.src(["./src/themes/night/fonts/**"]).pipe(gulp.dest("./src/styles/themes/night/fonts")) })执行上述命令,就会生成两套命名空间的样式。
computed: { //获取当前主题 theme() { return this.$store.state.setting.theme } }, watch: { theme: { handler(val) { //监听主题,然后设置主题命名空间 的类名 const body = document.getElementsByTagName("body") body[0].className = val }, immediate: true } },这样就可以切换element-ui的主题了。但是对于普通我们自定义的变量,还不能跟随主题变换,这个最后面一起说。
computed: { theme() { return this.$store.state.setting.theme } }, watch: { theme: { handler(val) { const body = document.getElementsByTagName("body") body[0].className = val const theme = val this.setHeadStyle(theme) }, immediate: true } }, methods: { /** * @description: 动态加载主题样式 * @return {*} * @author: syx */ setHeadStyle(themeName) { var head = document.getElementsByTagName("HEAD").item(0) var style = document.createElement("link") //给样式添加一个id 用于切换主题时删除标签 style.id = "theme_link" style.href = `服务器访问路径${themeName}/index.css` style.rel = "stylesheet" style.type = "text/css" const themeLinkTag = document.getElementById("theme_link") if (themeLinkTag) { head.removeChild(themeLinkTag) } head.appendChild(style) } }这样就可以实现多套element-ui主题的动态切换了。
上面说的切换主题仅仅只是切换了 element-ui的主题。对于我们自定义的变量,并不会切换,所以我们要将自己的主题变量也按不同主题来控制。因此我们需要用到强大的scss。
目录结构大致如下:
src styles themes //主题文件夹 index.scss //引入所有主题 normal.scss //正常模式主题变量 night.scss //夜间模式主题变量 themes //其实把这主题放在服务器上,项目以链接方式访问更ok night //基于element-variables.scss 生成的主题样式文件 night-gulp //经过gulp命令生成的命门空间样式文件 normal //基于element-variables.scss 生成的,然后使用gulp构建的命名空间样式 normal-gulp //经过gulp命令生成的命门空间样式文件 //==========================================================
@import "./night.scss"; @import "./normal.scss"; $themes:( normal:$normal_theme,night:$night_theme ); //遍历主题map @mixin themeify { @each $theme-name,$theme-map in $themes { //global 把局部变量强升为全局变量 $theme-map:$theme-map !global; //判断html的data-theme的属性值 # { }是sass的插值表达式 //& sass嵌套里的父容器标识 @content是混合器插槽,像vue的slot [data-theme="# { $theme-name } "] & { @content; } }}//声明一个根据Key获取颜色的function @function themed($key) { @return map-get($theme-map,$key); } //获取背景颜色 @mixin background_color($color) { @include themeify { background-color:themed($color) !important; } }//获取字体颜色 @mixin font_color($color) { @include themeify { color:themed($color) !important; } }//获取边框颜色 @mixin border_color($color) { @include themeify { border-color:themed($color) !important; } }//获取边框颜色 @mixin border_line_color($color,$num:1px) { @include themeify { border:$num solid themed($color) !important; } }// 阴影 @mixin box-shadowr($shadows,$color) { @include themeify { box-shadow:$shadows themed($color) !important; } }//还可以自定义其他属性.... // /src/styles/themes/normal.scss $night_theme:( main_color:#217acb, } // /src/styles/themes/night.scss $night_theme:( main_color:#001e3d, }然后加载项目时先加载主题变量
//vue.config.js module.exports = { css: { // 是否使用css分离插件 ExtractTextPlugin //如果需要css热更新就设置为false,打包时候要改为true extract: false, // 开启 CSS source maps? sourceMap: true, // css预设器配置项 loaderOptions: { sass: { // @/ is an alias to src/ // so this assumes you have a file named `src/variables.scss` prependData: `@import "@/styles/themes/index.scss";` } } }, }页面上使用主题变量
//设置背景颜色 @include background_color("main_color"); //设置字体颜色 @include font_color("main_color"); //设置边框颜色 @include border_color("main_color"); //设置 1px边框 1px可不传 或传 其他像素值 @include border_line_color("main_color", "1px"); //设置 阴影 @include shadowr("main_color");在store状态管理器新增一个theme主题变量值
<template> <div id="app"> <!-- 页面切换容器 --> <router-view /> </div> </template> <script> export default { name: "App", computed: { theme() { return this.$store.state.setting.theme } }, watch: { theme: { handler(val) { //命名空间切换样式类 const body = document.getElementsByTagName("body") body[0].className = val const theme = val this.setHeadStyle(theme) window.document.documentElement.setAttribute("data-theme", theme) }, immediate: true } }, methods: { /** * @description: 动态加载主题样式 * @return {*} * @author: syx */ setHeadStyle(themeName) { var head = document.getElementsByTagName("HEAD").item(0) var style = document.createElement("link") style.id = "theme_link" style.href = require(`@/themes/${themeName}-gulp/index.css`) style.rel = "stylesheet" style.type = "text/css" const themeLinkTag = document.getElementById("theme_link") if (themeLinkTag) { head.removeChild(themeLinkTag) } head.appendChild(style) } } } </script> <style> #app { } </style> //引入path var path = require("path") //引入gulp var gulp = require("gulp") //引入gulp-clean-css var cleanCSS = require("gulp-clean-css") //引入gulp-css-wrap var cssWrap = require("gulp-css-wrap") //创建一个命令(任务) normal-theme 执行此命令,会进行如下操作 gulp.task("normal-theme", function() { //导入文件 return gulp.src(path.resolve("./src/themes/normal/index.css")) /* 找需要添加命名空间的css文件,支持正则表达式 */ .pipe(cssWrap({ selector: ".normal" /* 添加的命名空间 */ })) .pipe(cleanCSS()) .pipe(gulp.dest("./src/themes/normal-gulp")) /* 存放的目录 */ }) //把字体文件也导入 gulp.task("normal-theme-font", function() { return gulp.src(["./src/themes/normal/fonts/**"]).pipe(gulp.dest("./src/themes/normal-gulp/fonts")) }) //创建一个命令(任务) normal-theme 执行此命令,会进行如下操作 gulp.task("night-theme", function() { //导入文件 return gulp.src(path.resolve("./src/themes/night/index.css")) /* 找需要添加命名空间的css文件,支持正则表达式 */ .pipe(cssWrap({ selector: ".night" /* 添加的命名空间 */ })) .pipe(cleanCSS()) .pipe(gulp.dest("./src/themes/night-gulp")) /* 存放的目录 */ }) //把字体文件也导入 gulp.task("night-theme-font", function() { return gulp.src(["./src/themes/night/fonts/**"]).pipe(gulp.dest("./src/themes/night-gulp/fonts")) })总结