vue,elementUI切换主题,自定义主题
本文介绍两种elementUI切换主题色的方法
项目示例:http://test.ofoyou.com/theme/
git代码:记得star哦,谢谢
1:官方提供的方法,直接修改scss文件达到修改目的,开发人员使用(比官网容易理解,有图有真相)。
2:通过选颜色值在项目中达到换肤目的,用户使用。此方法根据官方主题切换修改而来
先搭建项目:
npm install -g vue //全局安装vue
npm install -g webpack //全局安装webpack
npm install -g vue-cli //全局安装vue-cli
---->
进入项目目录--->
vue-init webpack my-project (vue init webpack my-project 这个官方已不用,使用会报错)
然后一次做下去就好了--->
安装elementUI :npm i element-ui -S
安装sass: npm install node-sass sass-loader --save-dev
项目结构 -----------------运行结果
1. 第一种方法,官方提供的方法,直接修改scss
在main.js引入elementUI,以及主题:(主题是可以自己设置下载配置的--官方工具)
然后在项目src->assets目录下创建element-variables.scss 内容可以从官网复制过来, 然后在main.js引入,见上图注释的代码
结束第一种,可以随便写几个element组件试试下
2:通过选颜色值在项目中达到换肤目的,根据官方修改主题项目修改而来
说明:项目主题分为两部分,一个是element组件主题,一个是自己定义组件或者DOM主题。
此方法主要思路就是:用户先从线上拉去配置主题的css文件,当用户更改颜色后,在把css文件里面所有的颜色值
替换掉,然后把这个css文件重新插入到html中达到改变颜色。
在这里都需要修改再方法1的基础上进行扩展:在element-variables.scss添加 默认我们自己设置的颜色。
当然这个颜色也可以在其他公共css修改。
1.
2. 安装两个插件:
npm install css-color-function
npm install object-assign
3.
文件在文章上面项目地址里面,下面罗列出来:
color.js 文件内容
import color from 'css-color-function' import formula from './formula.json' const generateColors = primary => { let colors = {} console.log(primary) Object.keys(formula).forEach(key => { const value = formula[key].replace(/primary/g, primary) colors[key] = color.convert(value) }) console.log(colors) return colors } export default generateColors
formula.json文件内容:
{ "shade-1": "color(primary shade(10%))", "light-1": "color(primary tint(10%))", "light-2": "color(primary tint(20%))", "light-3": "color(primary tint(30%))", "light-4": "color(primary tint(40%))", "light-5": "color(primary tint(50%))", "light-6": "color(primary tint(60%))", "light-7": "color(primary tint(70%))", "light-8": "color(primary tint(80%))", "light-9": "color(primary tint(90%))" }
4. 从 unpkg.com/element-ui/lib/theme-chalk/index.css 把最新css文件复制下来copy到项目静态文件目录中:
因为:项目中是先从element官方拉取主题css,如果拉取不到再去本地找备用的。
5.接下来就是写代码了。在App.vue上引入自定义的修改主题组件,在随便弄些element组件观察变化:
5. 写组件:Theme.vue
<!-- 切换主题色 --> <template> <div> <el-color-picker @change="colorChange" v-model="colors.primary" ></el-color-picker> </div> </template> <script> import generateColors from "../../utils/color"; import objectAssign from "object-assign"; export default { name: "App", data() { return { originalStylesheetCount: -1,//记录当前已引入style数量 originalStyle: "",//获取拿到的.css的字符串 colors: { //颜色选择器默认颜色值,这个值要和element-variables一样 primary: "#409EFF" }, // primaryColor: "", //提交成功后设置默认颜色 cssUrl: [ "//unpkg.com/element-ui/lib/theme-chalk/index.css", "./static/css/index.css" ] }; }, methods: { colorChange(e) { if(!e)return; localStorage.setItem('color',e) this.primaryColor = this.colors.primary; this.colors = objectAssign( {}, this.colors, generateColors(this.colors.primary) ); this.writeNewStyle(); }, writeNewStyle() { let cssText = this.originalStyle; Object.keys(this.colors).forEach(key => { cssText = cssText.replace( new RegExp("(:|\\s+)" + key, "g"), "$1" + this.colors[key] ); }); if (this.originalStylesheetCount === document.styleSheets.length) { // 如果之前没有插入就插入 const style = document.createElement("style"); style.innerText = ".primaryColor{background-color:" + this.colors.primary + "}" + cssText; document.head.appendChild(style); } else { // 如果之前没有插入就修改 document.head.lastChild.innerText = ".primaryColor{background-color:" + this.colors.primary + "} " + cssText; } }, getIndexStyle(url) { let that = this; var request = new XMLHttpRequest(); request.open("GET", url); request.onreadystatechange = function() { if ( request.readyState === 4 && (request.status == 200 || request.status == 304) ) { // 调用本地的如果拿不到会得到html,html是不行的 if (request.response && !/DOCTYPE/gi.test(request.response)) { that.originalStyle = that.getStyleTemplate(request.response); that.writeNewStyle() } else { that.originalStyle = ""; } } else { that.originalStyle = ""; } }; request.send(null); }, getStyleTemplate(data) { const colorMap = { "#3a8ee6": "shade-1", "#409eff": "primary", "#53a8ff": "light-1", "#66b1ff": "light-2", "#79bbff": "light-3", "#8cc5ff": "light-4", "#a0cfff": "light-5", "#b3d8ff": "light-6", "#c6e2ff": "light-7", "#d9ecff": "light-8", "#ecf5ff": "light-9" }; Object.keys(colorMap).forEach(key => { const value = colorMap[key]; data = data.replace(new RegExp(key, "ig"), value); }); return data; } }, mounted() { // 默认从线上官方拉取最新css,2秒钟后做一个检查没有拉到就从本地在拉下 let that = this; // 如果是记住用户的状态就需要,在主题切换的时候记录颜色值,在下次打开的时候从新赋值 this.colors.primary = localStorage.getItem('color')||this.colors.primary//例如 this.getIndexStyle(this.cssUrl[0]); setTimeout(function() { if (that.originalStyle) { return; } else { that.getIndexStyle(that.cssUrl[1]); } }, 2000); this.$nextTick(() => { // 获取页面一共引入了多少个style 文件 this.originalStylesheetCount = document.styleSheets.length; }); } }; </script> <style> </style>