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 相关文章推荐
xml 与javascript结合的问题解决方法
Mar 24 Javascript
JQuery上传插件Uploadify使用详解及错误处理
Apr 27 Javascript
window.open打开页面居中显示的示例代码
Dec 27 Javascript
jquery实现非叠加式的搜索框提示效果
Jan 07 Javascript
基于jQuery的图片不完全按比例自动缩小
Jul 11 Javascript
JS仿淘宝实现的简单滑动门效果代码
Oct 14 Javascript
jQuery模拟爆炸倒计时功能实例代码
Aug 21 jQuery
VUEJS 2.0 子组件访问/调用父组件的实例
Feb 10 Javascript
node实现基于token的身份验证
Apr 09 Javascript
vue路由组件按需加载的几种方法小结
Jul 12 Javascript
微信小程序http连接访问解决方案的示例
Nov 05 Javascript
微信小程序实现自定义动画弹框/提示框的方法实例
Nov 06 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脚本的10个技巧(3)
2006/10/09 PHP
PHP 抓取新浪读书频道的小说并生成txt电子书的代码
2009/12/18 PHP
php unset全局变量运用问题的深入解析
2013/06/17 PHP
详解PHP错误日志的获取方法
2015/07/20 PHP
php is_executable判断给定文件名是否可执行实例
2016/09/26 PHP
JavaScript与函数式编程解释
2007/04/27 Javascript
比较搞笑的js陷阱题
2010/02/07 Javascript
利用JQuery的load函数动态加载其它页面的内容的实现代码
2010/12/14 Javascript
js实现的点击div区域外隐藏div区域
2014/06/30 Javascript
Jquery弹出层插件ThickBox的使用方法
2014/12/09 Javascript
jQuery获得包含margin的outerWidth和outerHeight的方法
2015/03/25 Javascript
js与jQuery实现checkbox复选框全选/全不选的方法
2016/01/05 Javascript
JavaScript知识点总结之如何提高性能
2016/01/15 Javascript
HTML页面,测试JS对C函数的调用简单实例
2016/08/09 Javascript
security.js实现的RSA加密功能示例
2018/06/06 Javascript
JS实现的视频弹幕效果示例
2018/08/17 Javascript
node.js使用fs读取文件出错的解决方案
2019/10/23 Javascript
详解ES6 CLASS在微信小程序中的应用实例
2020/04/24 Javascript
node.js爬虫框架node-crawler初体验
2020/10/29 Javascript
Vue中避免滥用this去读取data中数据
2021/03/02 Vue.js
[00:36]DOTA2上海特级锦标赛 LGD战队宣传片
2016/03/04 DOTA
基于Python闭包及其作用域详解
2017/08/28 Python
python实现五子棋小程序
2019/06/18 Python
python 图片二值化处理(处理后为纯黑白的图片)
2019/11/01 Python
Python virtualenv虚拟环境实现过程解析
2020/04/18 Python
Python 用__new__方法实现单例的操作
2020/12/11 Python
TripAdvisor台湾:全球最大旅游网站
2018/08/26 全球购物
Woods官网:加拿大最古老、最受尊敬的户外品牌之一
2020/09/12 全球购物
大学生水文观测实习自我鉴定
2013/09/29 职场文书
上班迟到检讨书300字
2014/10/18 职场文书
2015年社区创卫工作总结
2015/04/21 职场文书
写给老师的保证书
2015/05/09 职场文书
离婚起诉书范本
2015/05/18 职场文书
家长对学校的意见和建议
2015/06/03 职场文书
《分一些蚊子进来》读后感3篇
2020/01/09 职场文书
聊一聊python常用的编程模块
2021/05/14 Python