赞
踩
自定义主题色包含以下两种,并且这两种的主题色需要同步
- element-ui的主题色
- 程序员自己写的样式中的主题色
我参考
- 一篇博客:vue,elementUI切换主题,自定义主题 - 小兔额乖乖 - 博客园
- 一个开源框架:腾讯的tDesign搭建的开源框架——TDesign Vue Next Starter
输出了此篇文章
说明1:小兔额乖乖文章中的项目示例,在修改主题色后,刷新一下,鼠标hover时会有问题,此问题在本篇文章中已经解决
说明2:我曾经尝试完全模仿腾讯那个框架的思路。但是此思路不适用于element-ui这个框架,会报错
说明3:下面的正文中,项目中修改主题色时,会运行 document.head.appendChild(style) ,修改一次颜色就会添加一个stylesheet,有兴趣的同学可以优化一下,改成替换掉上一次的style。
以下是正文
---------------------------------------------------------------------------------------------------------------------------------
① vue-cli3创建项目
vue create vue-custom-theme
② 安装element-ui相关
安装elementUI
npm i element-ui -S
安装sass
npm install node-sass@4.11.0 sass-loader@7.1.0 -D
启动项目
npm run serve
①在main,js中
- import ElementUI from 'element-ui'
- import './styles.scss'
- Vue.use(ElementUI)
②给一个默认的主题色【此步骤可省略,不需要。因为可以在Theme.vue中直接从后台获取默认主题(this.$store.state.sysConfig.theme)。this.$store.state.sysConfig.theme是在后台获取的,存储在了vuex里面,获取时机是全局路由拦截,在进入页面之前获取的】
用户先从线上拉去配置主题的css文件,当用户更改颜色后,在把css文件里面所有的颜色值替换掉,然后把这个css文件重新插入到html中达到改变颜色。
在这里都需要修改再方法1的基础上进行扩展:在element-variables.scss(大部分项目都是)添加 默认我们自己设置的颜色。
当然这个颜色也可以在其他公共css修改。我是在style.scss中修改的,如下
style.scss
- /* theme color */
- $--color-primary: #ff6f4b;
-
- /* icon font path, required */
- $--font-path: '~element-ui/lib/theme-chalk/fonts';
-
- @import "~element-ui/packages/theme-chalk/src/index";
①安装两个插件
- npm install css-color-function
-
- npm install object-assign
③ 从 unpkg.com/element-ui/lib/theme-chalk/index.css 把最新css文件复制下来copy到项目静态文件目录中:
④ 接下来就是写代码了。在App.vue上引入自定义的修改主题组件,再随便弄些element组件观察变化:
⑤写组件:Theme.vue
- <!-- 切换主题色 -->
- <template>
- <div class="handle-theme">
- <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: {
-
- primary: '#ff6f4b',// this.$store.state.sysConfig.theme,
- success: '#00c5bd',
- warning: '#f39800',
- danger: '#f56c6c',
- info: '#909399'
- },
- // primaryColor: "", //提交成功后设置默认颜色
- cssUrl: [
- '//unpkg.com/element-ui/lib/theme-chalk/index.css',
- process.env.BASE_URL + 'static/css/index.css'
- ]
- };
- },
- methods: {
- initTheme() {
- // 默认从线上官方拉取最新css,2秒钟后做一个检查没有拉到就从本地在拉下
- // 如果是记住用户的状态就需要,在主题切换的时候记录颜色值,在下次打开的时候从新赋值
- this.colors.primary = localStorage.getItem('color') || this.colors.primary; // 例如
- // this.getIndexStyle(this.cssUrl[0]);
- // setTimeout(() =>{
- // if (this.originalStyle) {
- // return;
- // } else {
- this.getIndexStyle(this.cssUrl[1]);
- // }
- // }, 2000);
- this.$nextTick(() => {
- // 获取页面一共引入了多少个style 文件
- this.originalStylesheetCount = document.styleSheets.length;
- });
- },
- colorChange(e) {
- if (!e) return;
- this.primaryColor = e;
- localStorage.setItem('color', e);
-
- let primarySeries = this.generateColors('p', e)
- let successSeries = this.generateColors('s', this.colors.success)
- let warningSeries = this.generateColors('w', this.colors.warning)
- let dangerSeries = this.generateColors('d', this.colors.danger)
- let infoSeries = this.generateColors('i', this.colors.info)
-
- this.colors = objectAssign(
- {},
- this.colors,
- primarySeries,
- successSeries,
- warningSeries,
- dangerSeries,
- infoSeries
- );
- 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]
- );
- });
- const style = document.createElement('style');
- style.innerText = `
- :root{
- --primary-color: ${this.colors.primary};
- --primary-color-light-1:${this.colors['pl-1']};
- --primary-color-light-2:${this.colors['pl-2']};
- --primary-color-light-3:${this.colors['pl-3']};
- --primary-color-light-4:${this.colors['pl-4']};
- --primary-color-light-5:${this.colors['pl-5']};
- --primary-color-light-6:${this.colors['pl-6']};
- --primary-color-light-7:${this.colors['pl-7']};
- --primary-color-light-8:${this.colors['pl-8']};
- --primary-color-light-9:${this.colors['pl-9']};
- }${cssText}`;
- // ":root{--primary-color:" + this.colors.primary + "}" + cssText;
- document.head.appendChild(style);
- // if (this.originalStylesheetCount === document.styleSheets.length) {
- // // 如果之前没有插入就插入
- // const style = document.createElement("style");
- // style.innerText =
- // ":root{--primary-color:" + this.colors.primary + "}" + cssText;
- // document.head.appendChild(style);
- // } else {
- // // 如果之前没有插入就修改
- // document.head.lastChild.innerText =
- // ":root{--primary-color:" +
- // this.colors.primary +
- // "} " +
- // cssText;
- // }
- },
- getIndexStyle(url) {
- var request = new XMLHttpRequest();
- request.open('GET', url);
- request.onreadystatechange = () => {
- if (
- request.readyState === 4 &&
- (request.status == 200 || request.status == 304)
- ) {
- // 调用本地的如果拿不到会得到html,html是不行的
- if (request.response && !/DOCTYPE/gi.test(request.response)) {
- this.originalStyle = this.getStyleTemplate(request.response);
- this.colorChange(this.colors.primary);
- } else {
- this.originalStyle = '';
- }
- } else {
- this.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",
-
- '#3a8ee6': 'ps-1',
- '#409eff': 'primary',
- '#53a8ff': 'pl-1',
- '#66b1ff': 'pl-2',
- '#79bbff': 'pl-3',
- '#8cc5ff': 'pl-4',
- '#a0cfff': 'pl-5',
- '#b3d8ff': 'pl-6',
- '#c6e2ff': 'pl-7',
- '#d9ecff': 'pl-8',
- '#ecf5ff': 'pl-9',
-
- '#5daf34': 'ss-1', // is-plain:active
- '#67c23a': 'success', // success
- '#76c84e': 'sl-1', // 没有
- '#85ce61': 'sl-2', // hover color
- '#95d475': 'sl-3', // 没有
- '#a4da89': 'sl-4', // is-disabled hover color
- '#b3e19d': 'sl-5', // is-disabled color
- '#c2e7b0': 'sl-6', // border-color
- '#d1edc4': 'sl-7', // 没有
- '#e1f3d8': 'sl-8', // light
- '#f0f9eb': 'sl-9', // lighter
-
- '#cf9236': 'ws-1', // is-plain:active
- '#E6A23C': 'warning', // success
- '#e9ab50': 'wl-1', // 没有
- '#ebb563': 'wl-2', // hover color
- '#eebe77': 'wl-3', // 没有
- '#f0c78a': 'wl-4', // is-disabled hover color
- '#f3d19e': 'wl-5', // is-disabled color
- '#f5dab1': 'wl-6', // border-color
- '#f8e3c5': 'wl-7', // 没有
- '#faecd8': 'wl-8', // light
- '#fdf6ec': 'wl-9', // lighter
-
- '#dd6161': 'ds-1', // is-plain:active
- '#F56C6C': 'danger', // success
- '#f67b7b': 'dl-1', // 没有
- '#f78989': 'dl-2', // hover color
- '#f89898': 'dl-3', // 没有
- '#f9a7a7': 'dl-4', // is-disabled hover color
- '#fab6b6': 'dl-5', // is-disabled color
- '#fbc4c4': 'dl-6', // border-color
- '#fcd3d3': 'dl-7', // 没有
- '#fde2e2': 'dl-8', // light
- '#fef0f0': 'dl-9', // lighter
-
- '#82848a': 'is-1', // is-plain:active
- '#909399': 'info', // success
- '#9b9ea3': 'il-1', // 没有
- '#a6a9ad': 'il-2', // hover color
- '#b1b3b8': 'il-3', // 没有
- '#bcbec2': 'il-4', // is-disabled hover color
- '#c8c9cc': 'il-5', // is-disabled color
- '#d3d4d6': 'il-6', // border-color
- '#dedfe0': 'il-7', // 没有
- '#e9e9eb': 'il-8', // light
- '#f4f4f5': 'il-9'// lighter
- };
- Object.keys(colorMap).forEach((key) => {
- const value = colorMap[key];
- data = data.replace(new RegExp(key, 'ig'), value);
- });
- return data;
- }
- },
- mounted() {
- this.initTheme();
- // 默认从线上官方拉取最新css,2秒钟后做一个检查没有拉到就从本地在拉下
- // let that = this;
- // 如果是记住用户的状态就需要,在主题切换的时候记录颜色值,在下次打开的时候从新赋值
- // this.colors.primary = localStorage.getItem('color')||this.colors.primary//例如
-
- // setTimeout(function() {
- // if (that.originalStyle) {
- // return;
- // } else {
- // that.getIndexStyle(that.cssUrl[1]);
- // }
- // }, 2000);
- // this.$nextTick(() => {
- // // 获取页面一共引入了多少个style 文件
- // this.originalStylesheetCount = document.styleSheets.length;
- // });
- }
- };
- </script>
- <style lang="scss">
-
- </style>

使用
- .boxDiv{
- padding:40px;
- background: var(--primary-color);
- box-shadow: 0 0 10px 8px var(--primary-color-light-8);
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。