Vue项目实现换肤功能的一种方案分析


Posted in Javascript onAugust 28, 2019

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

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

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 相关文章推荐
js中访问html中iframe的文档对象的代码[IE6,IE7,IE8,FF]
Jan 08 Javascript
Jqyery中同等与js中windows.onload的应用
May 10 Javascript
六款帮助你实现惊艳视差滚动效果的jQuery插件
Sep 14 Javascript
jQuery动画出现连续触发、滞后反复执行的解决方法
Jan 28 Javascript
jQuery实现checkbox全选的方法
Jun 10 Javascript
JavaScript判断手机号运营商是移动、联通、电信还是其他(代码简单)
Sep 25 Javascript
AngularJS入门教程之ng-checked 指令详解
Aug 01 Javascript
基于Phantomjs生成PDF的实现方法
Nov 07 Javascript
bootstrap配合Masonry插件实现瀑布式布局
Jan 18 Javascript
nuxt.js 缓存实践
Jun 25 Javascript
详解使用jest对vue项目进行单元测试
Sep 07 Javascript
react koa rematch 如何打造一套服务端渲染架子
Jun 26 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
vue项目中引入Sass实例方法
Aug 27 #Javascript
You might like
BBS(php & mysql)完整版(三)
2006/10/09 PHP
PHP统计当前在线用户数实例讲解
2015/10/21 PHP
php无限分类使用concat如何实现
2015/11/05 PHP
php打包网站并在线压缩为zip
2016/02/13 PHP
PHP addslashes()函数讲解
2019/02/03 PHP
php使用fullcalendar日历插件详解
2019/03/06 PHP
PHP强制转化的形式整理
2020/05/22 PHP
Prototype 1.5.0_rc1 及 Prototype 1.5.0 Pre0小抄本
2006/09/22 Javascript
jquery的颜色选择插件实例代码
2008/10/02 Javascript
js apply/call/caller/callee/bind使用方法与区别分析
2009/10/28 Javascript
JQuery切换显示的效果实例代码
2013/02/27 Javascript
JavaScript实现在页面间传值的方法
2015/04/07 Javascript
JQuery遍历DOM节点的方法
2015/06/11 Javascript
实例详解AngularJS实现无限级联动菜单
2016/01/15 Javascript
jQuery实现微信长按识别二维码功能
2016/08/26 Javascript
AngularJS表格样式简单设置方法示例
2017/03/03 Javascript
vue2.0实现分页组件的实例代码
2017/06/22 Javascript
JavaScript实现购物车基本功能
2017/07/21 Javascript
python下paramiko模块实现ssh连接登录Linux服务器
2015/06/03 Python
一步步教你用Python实现2048小游戏
2017/01/19 Python
Python 实现随机数详解及实例代码
2017/04/15 Python
Python 数据处理库 pandas 入门教程基本操作
2018/04/19 Python
Python处理命令行参数模块optpars用法实例分析
2018/05/31 Python
Python使用logging模块实现打印log到指定文件的方法
2018/09/05 Python
Python线上环境使用日志的及配置文件
2019/07/28 Python
python3读取csv文件任意行列代码实例
2020/01/13 Python
Python批量处理csv并保存过程解析
2020/05/16 Python
如何在Windows中安装多个python解释器
2020/06/16 Python
当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
2014/09/09 面试题
Windows和Linux动态库应用异同
2016/07/28 面试题
文明村创建实施方案
2014/03/27 职场文书
乡党委干部党的群众路线教育实践活动个人对照检查材料思想汇报
2014/10/01 职场文书
2014年控辍保学工作总结
2014/12/08 职场文书
2015试用期转正工作总结
2014/12/12 职场文书
幼儿园体操比赛口号
2015/12/25 职场文书
MySQL慢查询优化解决问题
2022/03/17 MySQL