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 相关文章推荐
jQuery EasyUI API 中文文档 - ValidateBox验证框
Oct 06 Javascript
jQuery1.6 使用方法一
Nov 23 Javascript
jquery实现图片左右切换的方法
May 07 Javascript
JavaScript获取当前运行脚本文件所在目录的方法
Feb 03 Javascript
jQuery中队列queue()函数的实例教程
May 03 Javascript
检查表单元素的值是否为空的实例代码
Jun 16 Javascript
BootStrap Table 分页后重新搜索问题的解决办法
Aug 08 Javascript
bootstrap模态框实现拖拽效果
Dec 14 Javascript
JS实现复选框的全选和批量删除功能
Apr 05 Javascript
JavaScript中in和hasOwnProperty区别详解
Aug 04 Javascript
JavaScript 对引擎、运行时、调用堆栈的概述理解
Oct 22 Javascript
VsCode里的Vue模板的实现
Aug 12 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
PHP函数func_num_args用法实例分析
2015/12/07 PHP
Laravel实现通过blade模板引擎渲染视图
2019/10/25 PHP
一些有关检查数据的JS代码
2006/09/07 Javascript
JQuery制作的放大效果的popup对话框(未添加任何jquery plugin)分享
2013/04/28 Javascript
JavaScript function 的 length 属性使用介绍
2014/09/15 Javascript
node.js使用require()函数加载模块
2014/11/26 Javascript
用js代码和插件实现wordpress雪花飘落效果的四种方法
2014/12/15 Javascript
jQuery圆形统计图开发实例
2015/01/04 Javascript
JavaScript监听文本框回车事件并过滤文本框空格的方法
2015/04/16 Javascript
JS实现的5级联动Select下拉选择框实例
2015/08/17 Javascript
跨域请求的完美解决方法(JSONP, CORS)
2016/06/12 Javascript
微信小程序 rpx 尺寸单位详细介绍
2016/10/13 Javascript
JS实现的几个常用算法
2016/11/12 Javascript
JS 调用微信扫一扫功能
2016/12/22 Javascript
vue.js事件处理器是什么
2017/03/20 Javascript
vue-axios使用详解
2017/05/10 Javascript
利用vue+elementUI实现部分引入组件的方法详解
2017/11/22 Javascript
vue项目中使用百度地图的方法
2018/06/08 Javascript
vue组件从开发到发布的实现步骤
2018/11/11 Javascript
你可能不知道的CORS跨域资源共享
2019/03/13 Javascript
JS实现的自定义map方法示例
2019/05/17 Javascript
[02:47]3.19DOTA2发布会 国服成长历程回顾
2014/03/25 DOTA
python 字典(dict)遍历的四种方法性能测试报告
2014/06/25 Python
尝试用最短的Python代码来实现服务器和代理服务器
2016/06/23 Python
Python 闭包的使用方法
2017/09/07 Python
pandas 时间格式转换的实现
2019/07/06 Python
CSS3 不定高宽垂直水平居中的几种方式
2020/03/26 HTML / CSS
英国领先的露营和露营车品牌之一:OLPRO
2019/08/06 全球购物
编写类String的构造函数、析构函数和赋值函数
2012/05/29 面试题
一道写SQL的面试题和答案
2013/11/19 面试题
毕业证丢失证明
2014/01/15 职场文书
村委会主任先进事迹
2014/01/15 职场文书
早会主持词
2014/03/17 职场文书
拔河比赛口号
2014/06/10 职场文书
初中军训感言
2015/08/01 职场文书
Python爬虫数据的分类及json数据使用小结
2021/03/29 Python