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解析与序列化json数据(二)序列化探讨
Feb 01 Javascript
JavaScript实现复制功能各浏览器支持情况实测
Jul 18 Javascript
引用其它js时如何同时处理多个window.onload事件
Sep 02 Javascript
avalonjs实现仿微博的图片拖动特效
May 06 Javascript
SpringMVC框架下JQuery传递并解析Json格式的数据是如何实现的
Dec 10 Javascript
基于Jquery插件实现跨域异步上传文件功能
Apr 26 Javascript
IONIC自定义subheader的最佳解决方案
Sep 22 Javascript
适用于手机端的jQuery图片滑块动画
Dec 09 Javascript
AngularJS中$injector、$rootScope和$scope的概念和关联关系深入分析
Jan 19 Javascript
详解angularjs利用ui-route异步加载组件
May 21 Javascript
浅谈vue项目打包优化策略
Sep 29 Javascript
JS滚轮控制图片缩放大小和拖动的实例代码
Nov 20 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 curl抓取网页的介绍和推广及使用CURL抓取淘宝页面集成方法
2015/11/30 PHP
关于IFRAME 自适应高度的研究
2006/07/20 Javascript
javascript window对象属性整理
2009/10/24 Javascript
JS中不为人知的五种声明Number的方式简要概述
2013/02/22 Javascript
Document:getElementsByName()使用方法及示例
2013/10/28 Javascript
含有CKEditor的表单如何提交
2014/01/09 Javascript
使用FlexiGrid实现Extjs表格效果方法分享
2014/12/16 Javascript
JavaScript每天定时更换皮肤样式的方法
2015/07/01 Javascript
jquery+css实现的红色线条横向二级菜单效果
2015/08/22 Javascript
jQuery mobile 移动web(6)
2015/12/20 Javascript
JS组件Bootstrap dropdown组件扩展hover事件
2016/04/17 Javascript
Angular的Bootstrap(引导)和Compiler(编译)机制
2016/06/20 Javascript
JavaScript遍历Json串浏览器输出的结果不统一问题
2016/11/03 Javascript
使用AngularJS对表单提交内容进行验证的操作方法
2017/07/12 Javascript
Vue.js实现开发购物车功能的方法详解
2019/02/22 Javascript
JS中如何轻松遍历对象属性的方式总结
2019/08/06 Javascript
JavaScript中变量提升机制示例详解
2019/12/27 Javascript
python入门之语句(if语句、while语句、for语句)
2015/01/19 Python
Python爬虫爬验证码实现功能详解
2016/04/14 Python
用Pygal绘制直方图代码示例
2017/12/07 Python
Django中使用 Closure Table 储存无限分级数据
2019/06/06 Python
Python Threading 线程/互斥锁/死锁/GIL锁
2019/07/21 Python
Python openpyxl读取单元格字体颜色过程解析
2019/09/03 Python
解决python 上传图片限制格式问题
2019/10/30 Python
python创建n行m列数组示例
2019/12/02 Python
Opencv python 图片生成视频的方法示例
2020/11/18 Python
next在python中返回迭代器的实例方法
2020/12/15 Python
CSS3之边框多颜色Border-color属性使用示例
2013/10/11 HTML / CSS
美国波西米亚风格精品店:South Moon Under
2019/10/26 全球购物
潘多拉珠宝俄罗斯官方网上商店:PANDORA俄罗斯
2020/09/22 全球购物
专业求职信撰写要诀
2014/02/18 职场文书
小学生暑假家长评语
2014/04/17 职场文书
党的群众路线批评与自我批评范文
2014/10/16 职场文书
文明单位创建材料
2014/12/24 职场文书
2015年幼儿园师德师风建设工作总结
2015/10/23 职场文书
Pytest中skip skipif跳过用例详解
2021/06/30 Python