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中字符串拼接需注意的问题
Jul 13 Javascript
JS教程:window.location使用方法的区别介绍
Oct 04 Javascript
jquery上传插件fineuploader上传文件使用方法(jquery图片上传插件)
Dec 05 Javascript
JQuery弹出炫丽对话框的同时让背景变灰色
May 22 Javascript
BootStrap的alert提示框的关闭后再显示怎么解决
May 17 Javascript
Bootstrap Paginator分页插件使用方法详解
May 30 Javascript
js判断手机号是否正确并返回的实现代码
Jan 17 Javascript
angular.js中解决跨域问题的三种方式
Jul 12 Javascript
简单实现jquery隔行变色
Nov 09 jQuery
详解webpack编译多页面vue项目的配置问题
Dec 11 Javascript
详解基于Vue的支持数据双向绑定的select组件
Sep 02 Javascript
原生js无缝轮播插件使用详解
Mar 09 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获得网站访问统计信息类Compete API用法实例
2015/04/02 PHP
ThinkPHP2.x防范XSS跨站攻击的方法
2015/09/25 PHP
使用JavaScript创建新样式表和新样式规则
2016/06/14 PHP
PHP PDOStatement::getAttribute讲解
2019/02/01 PHP
通过修改referer下载文件的方法
2008/05/11 Javascript
js设置控件的隐藏与显示的两种方法
2014/08/21 Javascript
用原生js做个简单的滑动效果的回到顶部
2014/10/15 Javascript
深入解读JavaScript中的Iterator和for-of循环
2015/07/28 Javascript
基于JavaScript实现移动端TAB触屏切换效果
2015/10/20 Javascript
Bootstrap+jfinal实现省市级联下拉菜单
2016/05/30 Javascript
Javascript 实现简单计算器实例代码
2016/10/23 Javascript
js 动态生成json对象、时时更新json对象的方法
2016/12/02 Javascript
JS实现异步上传压缩图片
2017/04/22 Javascript
vue.js的手脚架vue-cli项目搭建的步骤
2017/08/30 Javascript
vuejs实现本地数据的筛选分页功能思路详解
2017/11/15 Javascript
Vue 页面权限控制和登陆验证功能的实例代码
2019/06/20 Javascript
[33:23]VG vs Pain 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
python实现随机密码字典生成器示例
2014/04/09 Python
在Python中使用Neo4j数据库的教程
2015/04/16 Python
python生成式的send()方法(详解)
2017/05/08 Python
在python里协程使用同步锁Lock的实例
2019/02/19 Python
Django单元测试工具test client使用详解
2019/08/02 Python
详解如何从TensorFlow的mnist数据集导出手写体数字图片
2019/08/05 Python
使用python-Jenkins批量创建及修改jobs操作
2020/05/12 Python
Django多数据库联用实现方法解析
2020/11/12 Python
浅析Python模块之间的相互引用问题
2021/02/26 Python
世界最大的私人旅行指南出版商:孤独星球
2016/08/23 全球购物
全球销量第一生发产品:Viviscal
2017/12/21 全球购物
SK-II神仙水美国官网:SK-II美国
2020/02/25 全球购物
历史学专业大学生找工作的自我评价
2013/10/16 职场文书
自强之星事迹材料
2014/05/12 职场文书
机电专业求职信
2014/06/14 职场文书
拓展训练激励口号
2014/06/17 职场文书
中学生自我评价范文
2015/03/03 职场文书
幼儿园国培研修日志
2015/11/13 职场文书
Spring 使用注解开发
2022/05/20 Java/Android