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实现代码
May 23 Javascript
玩转jQuery按钮 请告诉我你最喜欢哪些?
Jan 08 Javascript
javascript 自定义回调函数示例代码
Sep 26 Javascript
基于jQuery实现文本框缩放以及上下移动功能
Nov 24 Javascript
javascript中Number对象的toString()方法分析
Dec 20 Javascript
bootstrap多种样式进度条展示
Dec 20 Javascript
深入理解Javascript中的valueOf与toString
Jan 04 Javascript
利用VUE框架,实现列表分页功能示例代码
Jan 12 Javascript
WebGL学习教程之Three.js学习笔记(第一篇)
Apr 25 Javascript
JavaScript实现HTML导航栏下拉菜单
Nov 25 Javascript
vue 数据双向绑定的实现方法
Mar 04 Vue.js
uniapp引入支付宝原生扫码插件步骤详解
Jul 23 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如何透过ODBC来存取数据库
2006/10/09 PHP
PHP学习散记_编码(json_encode 中文不显示)
2011/11/10 PHP
浅析PHP中strlen和mb_strlen的区别
2014/08/31 PHP
总结PHP中初始化空数组的最佳方法
2019/02/13 PHP
JavaScript 工具库 Cloudgamer JavaScript Library v0.1 发布
2009/10/29 Javascript
侧栏跟随滚动的简单实现代码
2013/03/18 Javascript
在JavaScript中typeof的用途介绍
2013/04/11 Javascript
JS 日期比较大小的简单实例
2014/01/13 Javascript
yepnope.js使用详解及示例分享
2014/06/23 Javascript
node.js中的fs.lchmodSync方法使用说明
2014/12/16 Javascript
js+HTML5基于过滤器从摄像头中捕获视频的方法
2015/06/16 Javascript
基于jQuery实现音乐播放试听列表
2016/04/14 Javascript
ES6所改良的javascript“缺陷”问题
2016/08/23 Javascript
基于JavaScript实现的折半查找算法示例
2017/04/14 Javascript
详解基于node的前端项目编译时内存溢出问题
2017/08/01 Javascript
ES6 javascript中class静态方法、属性与实例属性用法示例
2017/10/30 Javascript
vuex操作state对象的实例代码
2018/04/25 Javascript
vue slots 组件的组合/分发实例
2018/09/06 Javascript
Typescript 中的 interface 和 type 到底有什么区别详解
2019/06/18 Javascript
QML实现圆环颜色选择器
2019/09/25 Javascript
vue mvvm数据响应实现
2020/11/11 Javascript
[04:26]DOTA2上海特锦赛小组赛第二日 TOP10精彩集锦
2016/02/27 DOTA
[01:12:40]DOTA2-DPC中国联赛 正赛 DLG vs XG BO3 第三场 1月25日
2021/03/11 DOTA
举例讲解Python中的身份运算符的使用方法
2015/10/13 Python
Django框架模型简单介绍与使用分析
2019/07/18 Python
pandas 对日期类型数据的处理方法详解
2019/08/08 Python
pytorch中交叉熵损失(nn.CrossEntropyLoss())的计算过程详解
2020/01/02 Python
python各层级目录下import方法代码实例
2020/01/20 Python
python求numpy中array按列非零元素的平均值案例
2020/06/08 Python
浅谈tensorflow使用张量时的一些注意点tf.concat,tf.reshape,tf.stack
2020/06/23 Python
.NET程序员的数据库面试题
2012/10/10 面试题
绿化工程实施方案
2014/03/17 职场文书
机械电子工程专业求职信
2014/06/22 职场文书
快消品行业营销模式与盈利模式分享
2019/09/27 职场文书
springboot临时文件存储目录配置方式
2021/07/01 Java/Android
Vue如何清空对象
2022/03/03 Vue.js