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 获取表单file全路径
Dec 31 Javascript
jQuery maxlength文本字数限制插件
Apr 16 Javascript
javascript算法学习(直接插入排序)
Apr 12 Javascript
Chrome Form多次提交表单问题的解决方法
May 09 Javascript
JS+DIV+CSS实现的经典标签切换效果代码
Sep 14 Javascript
JavaScript限定范围拖拽及自定义滚动条应用(3)
May 17 Javascript
Vue项目中quill-editor带样式编辑器的使用方法
Aug 08 Javascript
Vue引入jquery实现平滑滚动到指定位置
May 09 jQuery
微信小程序swiper禁止用户手动滑动代码实例
Aug 23 Javascript
jQuery实现可编辑的表格
Dec 11 jQuery
vue axios请求成功却进入catch的原因分析
Sep 08 Javascript
vue集成一个支持图片缩放拖拽的富文本编辑器
Jan 29 Vue.js
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 date与gmdate的获取日期的区别
2010/02/08 PHP
PHP实现根据浏览器跳转不同语言页面代码
2013/08/02 PHP
php源码之将图片转化为data/base64数据流实例详解
2016/11/27 PHP
在网页中控制wmplayer播放器
2006/07/01 Javascript
JavaScript 学习笔记一些小技巧
2010/03/28 Javascript
深入探讨JavaScript、JQuery屏蔽网页鼠标右键菜单及禁止选择复制
2014/06/10 Javascript
JSON.parse()和JSON.stringify()使用介绍
2014/06/20 Javascript
基于jquery实现的自动补全功能
2015/03/12 Javascript
基于jQuery的checkbox全选问题分析
2016/11/18 Javascript
JavaScript实现邮箱地址自动匹配功能代码
2016/11/28 Javascript
angular+ionic 的app上拉加载更新数据实现方法
2017/01/16 Javascript
用Nodejs搭建服务器访问html、css、JS等静态资源文件
2017/04/28 NodeJs
jQuery导航条固定定位效果实例代码
2017/05/26 jQuery
微信小程序 sha1 实现密码加密实例详解
2017/07/06 Javascript
浅谈JavaScript的innerWidth与innerHeight
2017/10/12 Javascript
JS实现简单获取最近7天和最近3天日期的方法
2018/04/18 Javascript
Vue登录主页动态背景短视频制作
2019/09/21 Javascript
JS使用H5实现图片预览功能
2019/09/30 Javascript
python抓取网页中图片并保存到本地
2015/12/01 Python
使用Python爬取最好大学网大学排名
2018/02/24 Python
Django框架登录加上验证码校验实现验证功能示例
2019/05/23 Python
对Pytorch神经网络初始化kaiming分布详解
2019/08/18 Python
python如何快速生成时间戳
2020/07/21 Python
python一些性能分析的技巧
2020/08/30 Python
GoDaddy英国:全球排名第一的域名注册商
2018/06/08 全球购物
韩国保养品、日本药妆购物网:小三美日
2018/12/30 全球购物
计算机网络毕业生自荐信
2013/10/01 职场文书
物理教育专业毕业生推荐信
2013/11/03 职场文书
副厂长岗位职责
2014/02/02 职场文书
《在山的那边》教学反思
2014/02/23 职场文书
大专生找工作自荐书
2014/06/10 职场文书
授权委托书怎么写
2014/09/25 职场文书
2014年安置帮教工作总结
2014/12/11 职场文书
向女朋友道歉的话
2015/01/20 职场文书
元旦联欢晚会主持词
2015/07/01 职场文书
千万级用户系统SQL调优实战分享
2022/03/03 MySQL