详解Vue 换肤方案验证


Posted in Javascript onAugust 28, 2019

本文的换肤方案灵感来自于 element-ui

需求:网站换肤,主题切换。网站的主题色可以在几种常用颜色之间进行切换,还有相关图片、图标也要跟随主题进行切换。

不多说,先看下最终的实现效果:

详解Vue 换肤方案验证

文章由两部分组成:css切换,图片图标切换

css切换

1.在 static 目录下新建一个 styles 文件夹,在 styles 下新建一个 theme.scss 文件(项目使用了sass,会自动编译成css文件,如果没有使用这些预处理工具可以直接新建 theme.css),将需要替换的 CSS 声明在此文件中。

.theme-test-btn {
  background-color: #409eff;
  border-color: #409eff;
}

.theme-test-btn:hover,
.theme-test-btn:focus {
  background-color: #66b1ff;
  border-color: #66b1ff;
}

2.在 src/assets/js/const/ 目录下新建 theme-colors.js,用于声明所有可选的主题,每种颜色都对应一个关键词,方便区分

const colors = [
  {
    themeId: 0,
    primaryBtn: '#409eff', // 主要按钮的背景色
    priBtnHover: '#66b1ff', // 主要按钮的悬浮、聚焦背景色
  },
  {
    themeId: 1,
    primaryBtn: '#67c23a',
    priBtnHover: '#85ce61',
  },
  {
    themeId: 2,
    primaryBtn: '#e6a23c',
    priBtnHover: '#ebb563',
  },
];

export default colors;

3.通过 ajax 获取 theme.css ,将颜色值替换为关键词。

data() {
  return {
    active: 0,
    themeStyleStr: '', // 存放 替换成关键词的 theme.css 内容
    colors: themeColors, // 所有可选的主题颜色数组。即:theme-colors.js 文件export的数组
  };
},
mounted() {
  // 通过 ajax 获取 theme.css 的内容,并将颜色值替换为关键词
  this.$http.getThemeFile().then(res => {
    this.themeStyleStr = this.getStyleTemplate(res);
  });
},
methods: {
  // 获取样式模板:将颜色值替换为关键词。
  getStyleTemplate(data) {
    let color = this.colors[0];
    delete color.themeId;
    let colorMap = {};
    Object.keys(color).forEach(key => {
      colorMap[color[key]] = key;
    });
    Object.keys(colorMap).forEach(key => {
      data = data.replace(new RegExp(key, 'ig'), colorMap[key]);
    });
    return data;
  },
}

this.$http.getThemeFile 方法

// 使用原生ajax获取换肤的样式文件
getThemeFile() {
  return new Promise(resolve => {
    const url = location.origin + '/static/styles/theme.css';
    const xhr = new XMLHttpRequest();
    xhr.onreadystatechange = () => {
      if (xhr.readyState === 4 && xhr.status === 200) {
        resolve(xhr.responseText);
      }
    };
    xhr.open('GET', url);
    xhr.send();
  });
}

4.把关键词再换回刚刚生成的相应的颜色值,并在页面上添加 style 标签

methods: {
  // 点击切换主题
  changeTheme(index) {
    this.active = index;
    this.setNewStyle(this.themeStyleStr, this.colors[index]);
  },
  // 根据选择的主题颜色,把关键词换成相应的主题颜色,并在页面上添加 style 标签
  setNewStyle(originalStyle, colors) {
    let oldEl = document.getElementById('theme-style');
    let cssText = originalStyle;
    Object.keys(colors).forEach(key => {
      cssText = cssText.replace(new RegExp(key, 'ig'), colors[key]);
    });
    const style = document.createElement('style');
    style.innerHTML = cssText;
    style.id = 'theme-style';
    oldEl ? document.head.replaceChild(style, oldEl) : document.head.appendChild(style);
  }
}

图片图标切换

1.图片切换和图标切换是同样的原理。在之前新建好的 theme.scss 文件追加图标引入的样式。

.theme-test-icon {
  background: url("/static/images/common/list-modify-icon.svg");
}

2.在之前新建好的 theme-colors.js 文件追加图标路径

/*图片统一使用一个路径,更换主题时需要在images文件夹下新建主题文件夹,与原始路径对应,图片文件名须一致
应避免 primaryBtn 与 primaryBtnHover 同时出现,因为正则匹配 primaryBtn 会把 primaryBtnHover 部分匹配出来,达不到效果*/
const colors = [
  {
    themeId: 0,
    primaryBtn: '#409eff', // 主要按钮的背景色
    priBtnHover: '#66b1ff', // 主要按钮的悬浮、聚焦背景色
    imagePath: '/static/images', // 图片绝对路径
  },
  {
    themeId: 1,
    primaryBtn: '#67c23a',
    priBtnHover: '#85ce61',
    imagePath: '/static/images/theme1',
  },
  {
    themeId: 2,
    primaryBtn: '#e6a23c',
    priBtnHover: '#ebb563',
    imagePath: '/static/images/theme2',
  },
];
export default colors;

3.引入需要主题切换的图片/图标,存放于 /static/images/ 之下,每个额外的主题图片需要一个文件夹进行存放,例如 /theme1 或者 /theme2。注意:各个主题的图片文件名要保持不变;图片路径是根据 theme.scss 里面引入图片样式的路径来决定的,可以根据项目实际情况进行调整。

详解Vue 换肤方案验证

以上,就是Vue项目实现换肤功能的一种方案。换肤功能的实现还有其他方法,欢迎一起交流学习。

Javascript 相关文章推荐
Javascript技术技巧大全(五)
Jan 22 Javascript
javascript中的对象创建 实例附注释
Feb 08 Javascript
JQuery判断子iframe何时加载完成解决方案
Aug 20 Javascript
JS OffsetParent属性深入解析
Jan 13 Javascript
javascript中HTMLDOM操作详解
Dec 11 Javascript
javascript算法题:求任意一个1-9位不重复的N位数在该组合中的大小排列序号
Apr 01 Javascript
JQuery中属性过滤选择器用法实例分析
May 18 Javascript
Jquery全选与反选点击执行一次的解决方案
Aug 14 Javascript
AngularJS基础 ng-show 指令简单示例
Aug 03 Javascript
你可能从未使用过的11+个JavaScript特性(小结)
Jan 08 Javascript
解决vue打包 npm run build-test突然不动了的问题
Nov 13 Javascript
Flexible.js可伸缩布局实现方法详解
Nov 13 Javascript
Vue项目实现换肤功能的一种方案分析
Aug 28 #Javascript
js遍历详解(forEach, map, for, for...in, for...of)
Aug 28 #Javascript
Angular6使用forRoot() 注册单一实例服务问题
Aug 27 #Javascript
jQuery - AJAX load() 实例用法详解
Aug 27 #jQuery
JS实现提示框跟随鼠标移动
Aug 27 #Javascript
js对象数组和对象的使用实例详解
Aug 27 #Javascript
vue递归组件实战之简单树形控件实例代码
Aug 27 #Javascript
You might like
php中处理模拟rewrite 效果
2006/12/09 PHP
获取PHP警告错误信息的解决方法
2013/06/03 PHP
递归实现php数组转xml的代码分享
2015/05/14 PHP
PHP序列化/对象注入漏洞分析
2016/04/18 PHP
PHP简单实现解析xml为数组的方法
2018/05/02 PHP
php提取微信账单的有效信息
2018/10/01 PHP
2007/12/23更新创意无限,简单实用(javascript log)
2007/12/24 Javascript
ExtJS 2.0实用简明教程 之获得ExtJS
2009/04/29 Javascript
jquery 表格分页等操作实现代码(pagedown,pageup)
2010/04/11 Javascript
Javascript数据结构与算法之列表详解
2015/03/12 Javascript
jQuery经过一段时间自动隐藏指定元素的方法
2015/03/17 Javascript
JS实现状态栏跑马灯文字效果代码
2015/10/24 Javascript
jQuery Easyui快速入门教程
2016/08/21 Javascript
微信小程序学习(4)-系统配置app.json详解
2017/01/12 Javascript
JavaScript数据结构中栈的应用之表达式求值问题详解
2017/04/11 Javascript
微信小程序 判断手机号的实现代码
2017/04/19 Javascript
发布一款npm包帮助理解npm的使用
2019/01/03 Javascript
vue实现文字横向无缝走马灯组件效果的实例代码
2019/04/09 Javascript
JS秒杀倒计时功能完整实例【使用jQuery3.1.1】
2019/09/03 jQuery
Vue最新防抖方案(必看篇)
2019/10/30 Javascript
使用JavaScript计算前一天和后一天的思路详解
2019/12/20 Javascript
[46:00]Ti4 冒泡赛第二轮LGD vs C9 2
2014/07/14 DOTA
[55:44]完美世界DOTA2联赛决赛 FTD vs Phoenix 第二场 11.08
2020/11/11 DOTA
Python函数学习笔记
2008/10/07 Python
python使用pandas实现数据分割实例代码
2018/01/25 Python
Python hexstring-list-str之间的转换方法
2019/06/12 Python
python实现视频读取和转化图片
2019/12/10 Python
Python代码注释规范代码实例解析
2020/08/14 Python
如何使用PyCharm引入需要使用的包的方法
2020/09/22 Python
Dyson加拿大官方网站:购买戴森吸尘器,风扇,冷热器及配件
2016/10/26 全球购物
最新大学职业规划书范文
2013/12/30 职场文书
霸气押韵的班级口号
2014/06/09 职场文书
售房委托书
2014/08/30 职场文书
离职证明标准格式
2014/09/15 职场文书
超市食品安全承诺书
2015/04/29 职场文书
2015年办公室文秘工作总结
2015/04/30 职场文书