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 相关文章推荐
javascript中动态加载js文件多种解决办法总结
Nov 15 Javascript
巧用replace将文字表情替换为图片
Apr 17 Javascript
JavaScript输出当前时间Unix时间戳的方法
Apr 06 Javascript
JavaScript中的some()方法使用详解
Jun 09 Javascript
iScroll.js 使用方法参考
May 16 Javascript
JS数组去掉重复数据只保留一条的实现代码
Aug 11 Javascript
JavaScript链式调用实例浅析
Dec 19 Javascript
js比较两个单独的数组或对象是否相等的实例代码
Apr 28 Javascript
vue配置nprogress实现页面顶部进度条
Sep 21 Javascript
Vue防止白屏添加首屏动画的实例
Oct 31 Javascript
javascript实现画板功能
Apr 12 Javascript
JavaScript async/await原理及实例解析
Dec 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
PHP CodeBase:将时间显示为"刚刚""n分钟/小时前"的方法详解
2013/06/06 PHP
PHP 5.5 创建和验证哈希最简单的方法详解
2013/11/07 PHP
php判断是否为json格式的方法
2014/03/04 PHP
建立良好体验度的Web注册系统ajax
2007/07/09 Javascript
jquery在Chrome下获取图片的长宽问题解决
2013/03/20 Javascript
文本域中换行符的替换示例
2014/03/04 Javascript
JS获得图片alt信息的方法
2015/04/01 Javascript
基于javascript代码实现通过点击图片显示原图片
2015/11/29 Javascript
日常收集整理的JavaScript常用函数方法
2015/12/10 Javascript
详解AngularJS Filter(过滤器)用法
2015/12/28 Javascript
使用NodeJs 开发微信公众号(三)微信事件交互实例
2016/03/02 NodeJs
JavaScript比较两个数组的内容是否相同(推荐)
2017/05/02 Javascript
fullPage.js和CSS3实现全屏滚动效果
2017/05/05 Javascript
利用JavaScript实现栈的数据结构示例代码
2017/08/02 Javascript
js实现登录注册框手机号和验证码校验(前端部分)
2017/09/28 Javascript
JavaScript实现多重继承的方法分析
2018/01/09 Javascript
React中this丢失的四种解决方法
2019/03/12 Javascript
简谈创建React Component的几种方式
2019/06/15 Javascript
webpack 动态批量加载文件的实现方法
2020/03/19 Javascript
js实现时间日期校验
2020/05/26 Javascript
Vue执行方法,方法获取data值,设置data值,方法传值操作
2020/08/05 Javascript
[45:44]完美世界DOTA2联赛PWL S2 FTD vs PXG 第一场 11.27
2020/12/01 DOTA
python操作MongoDB基础知识
2013/11/01 Python
Python自动化测试Eclipse+Pydev 搭建开发环境
2016/08/15 Python
解决HTML5中的audio在手机端和微信端的不能自动播放问题
2019/11/04 HTML / CSS
阿迪达斯德国官方网站:adidas德国
2017/07/12 全球购物
英国评分最高的女性剃须刀订阅盒:FFS Beauty
2018/01/25 全球购物
Feelunique德国官方网站:欧洲最大的在线美容零售商
2019/07/20 全球购物
护理学应聘自荐书范文
2014/02/05 职场文书
校园安全广播稿
2014/02/08 职场文书
少先队学雷锋活动总结范文
2014/03/09 职场文书
2015年医德医风工作总结
2015/04/02 职场文书
基石观后感
2015/06/12 职场文书
幼儿园庆六一主持词
2015/06/30 职场文书
解决Pytorch修改预训练模型时遇到key不匹配的情况
2021/06/05 Python
详解非极大值抑制算法之Python实现
2021/06/28 Python