详解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学习笔记之函数篇(四):arguments 对象
Nov 23 Javascript
基于豆瓣API+Angular开发的web App
Jan 02 Javascript
推荐一个自己用的封装好的javascript插件
Jan 29 Javascript
谈一谈javascript闭包
Jan 28 Javascript
js基本算法:冒泡排序,二分查找的简单实例
Oct 08 Javascript
jQuery 选择符详细介绍及整理
Dec 02 Javascript
浅析JavaScript的几种Math函数,random(),ceil(),round(),floor()
Dec 22 Javascript
微信小程序获取用户openid的实现
Dec 24 Javascript
Node.js HTTP服务器中的文件、图片上传的方法
Sep 23 Javascript
webpack4 配置 ssr 环境遇到“document is not defined”
Oct 24 Javascript
通过实例了解Javascript柯里化流程
Mar 03 Javascript
JavaScript使用prototype属性实现继承操作示例
May 22 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中的加密功能
2006/10/09 PHP
php防攻击代码升级版
2010/12/29 PHP
如何解决CI框架的Disallowed Key Characters错误提示
2013/07/05 PHP
PHP生成Gif图片验证码
2013/10/27 PHP
PHP模板引擎Smarty中变量的使用方法示例
2016/04/11 PHP
zend框架实现支持sql server的操作方法
2016/12/08 PHP
PHP简单实现冒泡排序的方法
2016/12/26 PHP
在IE浏览器中resize事件执行多次的解决方法
2011/07/12 Javascript
Raphael一个用于在网页中绘制矢量图形的Javascript库
2013/01/08 Javascript
jQuery实现返回顶部功能适合不支持js的浏览器
2014/08/19 Javascript
jquery获取当前日期的方法
2015/01/14 Javascript
分享jQuery网页元素拖拽插件
2020/12/01 Javascript
微信小程序 require机制详解及实例代码
2016/12/14 Javascript
JSON 数据格式详解
2017/09/13 Javascript
每个 JavaScript 工程师都应懂的33个概念
2018/10/22 Javascript
微信小程序实现左滑修改、删除功能
2020/10/19 Javascript
详解keep-alive + vuex 让缓存的页面灵活起来
2019/04/19 Javascript
react-intl实现React国际化多语言的方法
2020/09/27 Javascript
[01:19:11]Ti4 循环赛第二日 NaVi.us vs iG
2014/07/11 DOTA
python中pandas.DataFrame对行与列求和及添加新行与列示例
2017/03/12 Python
django 2.0更新的10条注意事项总结
2018/01/05 Python
python如何实现内容写在图片上
2018/03/23 Python
Python实现的个人所得税计算器示例
2018/06/01 Python
浅谈Python的条件判断语句if/else语句
2019/03/21 Python
使用python3调用wxpy模块监控linux日志并定时发送消息给群组或好友
2019/06/05 Python
python实现在cmd窗口显示彩色文字
2019/06/24 Python
PyChon中关于Jekins的详细安装(推荐)
2020/12/28 Python
python如何调用php文件中的函数详解
2020/12/29 Python
体育纪念品、亲笔签名的体育收藏品:Steiner Sports
2020/07/31 全球购物
启动一个线程是用run()还是start()
2016/12/25 面试题
演讲比赛获奖感言
2014/02/02 职场文书
事业单位绩效考核实施方案
2014/03/27 职场文书
优秀团支部申报材料
2014/12/26 职场文书
中秋节主题班会
2015/08/14 职场文书
教您:房贷工资收入证明应该怎么写?
2019/08/19 职场文书
MySQL悲观锁与乐观锁的实现方案
2021/11/02 MySQL