详解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 相关文章推荐
javascript 贪吃蛇实现代码
Nov 22 Javascript
jQuery的强大选择器小结
Dec 27 Javascript
javascript学习笔记(四) Number 数字类型
Jun 19 Javascript
js call方法详细介绍(js 的继承)
Nov 18 Javascript
javascript去除空格方法小结
May 21 Javascript
js+css实现上下翻页相册代码分享
Aug 18 Javascript
javascript超过容器后显示省略号效果的方法(兼容一行或者多行)
Jul 14 Javascript
老生常谈jacascript DOM节点获取
Apr 17 Javascript
JavaScript中防止微信浏览器被整体拖动的方法
Aug 25 Javascript
vue-cli 引入、配置axios的方法
May 08 Javascript
layui lay-verify form表单自定义验证规则详解
Sep 18 Javascript
实现一个简单得数据响应系统
Nov 11 Javascript
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跨站刷票的实现代码
2013/06/18 PHP
PHP中对缓冲区的控制实现代码
2013/09/29 PHP
php对数组内元素进行随机调换的方法
2015/05/12 PHP
PHP实现对二维数组某个键排序的方法
2016/09/14 PHP
PHP实现下载远程图片保存到本地的方法
2017/06/19 PHP
PHP中上传文件打印错误错误类型分析
2019/04/14 PHP
Whatever:hover 无需javascript让IE支持丰富伪类
2010/06/29 Javascript
基于Jquery的开发个代阴影的对话框效果代码
2011/07/28 Javascript
js 为label标签和div标签赋值的方法
2013/08/08 Javascript
Jquery validation remote 验证的缓存问题解决方法
2014/03/25 Javascript
javascript中的括号()用法小结
2014/04/14 Javascript
Jquery 效果使用详解
2015/11/23 Javascript
js实现可控制左右方向的无缝滚动效果
2016/05/29 Javascript
jQuery多文件异步上传带进度条实例代码
2016/08/16 Javascript
javascript字符串对象常用api函数小结(连接,替换,分割,转换等)
2016/09/20 Javascript
微信开发 js实现tabs选项卡效果
2016/10/28 Javascript
jQuery将表单序列化成一个Object对象的实例
2016/11/29 Javascript
从零开始学习Node.js系列教程五:服务器监听方法示例
2017/04/13 Javascript
node文字生成图片的示例代码
2017/10/26 Javascript
ES6的异步操作之promise用法和async函数的具体使用
2019/12/06 Javascript
[01:32]寻找你心中的那团火 DOTA2 TI9火焰传递活动今日开启
2019/05/16 DOTA
[54:15]DOTA2-DPC中国联赛 正赛 DLG vs Dragon BO3 第二场2月1日
2021/03/11 DOTA
归纳整理Python中的控制流语句的知识点
2015/04/14 Python
python 接口返回的json字符串实例
2018/03/27 Python
Python自动采集微信联系人的实现示例
2020/02/28 Python
Pytorch 使用CNN图像分类的实现
2020/06/16 Python
如何基于pandas读取csv后合并两个股票
2020/09/25 Python
利用HTML5的新特点实现图片文件异步上传
2014/05/29 HTML / CSS
HTML5本地存储之Web Storage详解
2016/07/04 HTML / CSS
朗仕(Lab series)英国官网:雅诗兰黛集团男士专属护肤品牌
2017/11/28 全球购物
化学相关工作求职信
2013/10/02 职场文书
业务员简历自我评价
2014/03/06 职场文书
委托证明书
2014/09/17 职场文书
领导干部“四风”问题批评与自我批评材料
2014/09/24 职场文书
军训新闻稿范文
2015/07/17 职场文书
numpy array找出符合条件的数并赋值的示例代码
2022/06/01 Python