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控制回车事件的代码
Feb 20 Javascript
jquery垂直公告滚动实现代码
Dec 08 Javascript
js中AppendChild与insertBefore的用法详细解析
Dec 16 Javascript
JS数组的赋值介绍
Mar 10 Javascript
一款简单的jQuery图片标注效果附源码下载
Mar 22 Javascript
使用JavaScript判断手机浏览器是横屏还是竖屏问题
Aug 02 Javascript
Angular 表单控件示例代码
Jun 26 Javascript
vue下跨域设置的相关介绍
Aug 26 Javascript
node.js操作MongoDB的实例详解
Oct 11 Javascript
JS实现区分中英文并统计字符个数的方法示例
Jun 09 Javascript
angular4自定义组件非input元素实现ngModel双向数据绑定的方法
Dec 28 Javascript
Vuejs通过拖动改变元素宽度实现自适应
Sep 02 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
15个小时----从修改程序到自己些程序
2006/10/09 PHP
PHP iconv 解决utf-8和gb2312编码转换问题
2010/04/12 PHP
解析如何用php screw加密php源代码
2013/06/20 PHP
Zend Framework前端控制器用法示例
2016/12/11 PHP
php分页查询的简单实现代码
2017/03/14 PHP
php常用经典函数集锦【数组、字符串、栈、队列、排序等】
2019/08/23 PHP
phpstudy后门rce批量利用脚本的实现
2019/12/12 PHP
js实现兼容IE6与IE7的DIV高度
2010/05/13 Javascript
当jQuery遭遇CoffeeScript的时候 使用分享
2011/09/17 Javascript
js中opener与parent的区别详细解析
2014/01/14 Javascript
jQuery判断指定id的对象是否存在的方法
2015/05/22 Javascript
javascript常用的方法分享
2015/07/01 Javascript
JQuery 的跨域方法推荐_可跨任何网站
2016/05/18 Javascript
Boostrap栅格系统与自己额外定义的媒体查询的冲突问题
2017/02/19 Javascript
javascript 删除数组元素和清空数组的简单方法
2017/02/24 Javascript
微信小程序实现富文本图片宽度自适应的方法
2019/01/20 Javascript
koa2 用户注册、登录校验与加盐加密的实现方法
2019/07/22 Javascript
Node Mongoose用法详解【Mongoose使用、Schema、对象、model文档等】
2020/05/13 Javascript
[09:47]2018DOTA2亚洲邀请赛4.5SOLO赛 No[o]ne vs Sumail
2018/04/06 DOTA
Windows下为Python安装Matplotlib模块
2015/11/06 Python
Python 中 list 的各项操作技巧
2017/04/13 Python
Python决策树分类算法学习
2017/12/22 Python
python实现堆和索引堆的代码示例
2018/03/19 Python
wxpython绘制音频效果
2019/11/18 Python
Python-numpy实现灰度图像的分块和合并方式
2020/01/09 Python
在css3中background-clip属性与background-origin属性的用法介绍
2012/11/13 HTML / CSS
Can a struct inherit from another class? (结构体能继承类吗)
2014/07/22 面试题
大学生职业规划前言模板
2013/12/27 职场文书
我的大学生活职业生涯规划
2014/01/02 职场文书
《小白兔和小灰兔》教学反思
2014/02/18 职场文书
2015年超市工作总结
2015/04/09 职场文书
运动会加油稿30字
2015/07/21 职场文书
2016年教师师德师风承诺书
2016/03/25 职场文书
JS ES6异步解决方案
2021/04/29 Javascript
解决persistence.xml配置文件修改存放路径的问题
2022/02/24 Java/Android
Mysql查询时间区间日期列表,不会由于数据表数据影响
2022/04/19 MySQL