详解Vue 换肤方案验证


Posted in Javascript onAugust 28, 2019

本文的换肤方案灵感来自于 element-ui

需求:网站换肤,主题切换。网站的主题色可以在几种常用颜色之间进行切换,还有相关图片、图标也要跟随主题进行切换。

不多说,先看下最终的实现效果:

详解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 相关文章推荐
收集的一些Array及String原型对象的扩展实现代码
Dec 05 Javascript
jquery load事件(callback/data)使用方法及注意事项
Feb 06 Javascript
javascript实现动态侧边栏代码
Feb 19 Javascript
php实例分享之实现显示网站运行时间
May 20 Javascript
JavaScript获取浏览器信息的方法
Nov 20 Javascript
JavaScript如何实现在文本框(密码框)输入提示语
Dec 25 Javascript
javascript移动开发中touch触摸事件详解
Mar 18 Javascript
BootStrap 动态表单效果
Jun 02 Javascript
bootstrap table服务端实现分页效果
Aug 10 Javascript
原生js封装添加class,删除class的实例
Nov 06 Javascript
js控制随机数生成概率代码实例
Mar 21 Javascript
如何使用RoughViz可视化Vue.js中的草绘图表
Jan 30 Vue.js
Vue项目实现换肤功能的一种方案分析
Aug 28 #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
You might like
PHP教程 基本语法
2009/10/23 PHP
php修改时间格式的代码
2011/05/29 PHP
PHP 安全检测代码片段(分享)
2013/07/05 PHP
php中实现可以返回多个值的函数实例
2015/03/21 PHP
php实现用于验证所有类型的信用卡类
2015/03/24 PHP
PHP实现登录搜狐广告获取广告联盟数据的方法【附demo源码】
2016/10/14 PHP
PHP实现Unicode编码相互转换的方法示例
2020/11/17 PHP
Javascript 调试利器 Firebug使用详解六
2009/07/05 Javascript
javascript中的107个基础知识收集整理 推荐
2010/03/29 Javascript
JS对img进行操作(换图片/切图/轮换/停止)
2013/04/17 Javascript
原生js和jquery中有关透明度设置的相关问题
2014/01/08 Javascript
node.js中的fs.write方法使用说明
2014/12/15 Javascript
javascript定时器完整实例
2015/02/10 Javascript
JS实现显示带倒影的图片横排居中放大展示特效实例【测试可用】
2016/08/23 Javascript
WEB 前端开发中防治重复提交的实现方法
2016/10/26 Javascript
详解JS中定时器setInterval和setTImeout的this指向问题
2017/01/06 Javascript
jQuery extend()详解及简单实例
2017/05/06 jQuery
JavaScript使用readAsDataUrl方法预览图片
2017/05/10 Javascript
微信小程序实现多个按钮toggle功能的实例
2017/06/13 Javascript
动态创建Angular组件实现popup弹窗功能
2017/09/15 Javascript
微信小程序tabbar底部导航
2018/11/05 Javascript
微信小程序防止多次点击跳转和防止表单组件输入内容多次验证功能(函数防抖)
2019/09/19 Javascript
微信小程序实现列表滚动头部吸顶的示例代码
2020/07/12 Javascript
python实现文件分组复制到不同目录的例子
2014/06/04 Python
python使用mailbox打印电子邮件的方法
2015/04/30 Python
Linux-ubuntu16.04 Python3.5配置OpenCV3.2的方法
2018/04/02 Python
解决python执行不输出系统命令弹框的问题
2019/06/24 Python
Django如何使用第三方服务发送电子邮件
2019/08/14 Python
Python如何读写二进制数组数据
2020/08/01 Python
使用HTML5和CSS3表单验证功能
2017/05/05 HTML / CSS
CSS3实现时间轴特效
2020/11/02 HTML / CSS
abstract 可以和 virtual 一起使用吗?可以和 override 一起使用吗?
2012/10/15 面试题
环保专业大学生职业规划设计
2014/01/10 职场文书
村长贪污检举信
2014/04/04 职场文书
2014年幼儿园德育工作总结
2014/12/17 职场文书
一文弄懂MySQL中redo log与binlog的区别
2022/02/15 MySQL