详解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 相关文章推荐
20个非常棒的Jquery实用工具 国外文章
Jan 01 Javascript
在网页中使用document.write时遭遇的奇怪问题
Aug 24 Javascript
jQuery选择器源码解读(七):elementMatcher函数
Mar 31 Javascript
JQuery遍历DOM节点的方法
Jun 11 Javascript
微信小程序 数据访问实例详解
Oct 08 Javascript
javascript回调函数的概念理解与用法分析
May 27 Javascript
jQuery之动画ajax事件(实例讲解)
Jul 18 jQuery
jQuery Layer弹出层传值到父页面的实现代码
Aug 17 jQuery
一个Vue视频媒体多段裁剪组件的实现示例
Aug 09 Javascript
微信小程序功能之全屏滚动效果的实现代码
Nov 22 Javascript
微信小程序实现动态显示和隐藏某个控件功能示例
Dec 14 Javascript
Vue.js实现备忘录功能
Jun 26 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
让CodeIgniter的ellipsize()支持中文截断的方法
2014/06/12 PHP
IE8对JS通过属性和数组遍历解析不一样的地方探讨
2013/05/06 Javascript
javascript中SetInterval与setTimeout的定时器用法
2015/08/24 Javascript
图解JavaScript中的this关键字
2020/05/28 Javascript
jQuery获取checkbox选中的值
2016/01/28 Javascript
jQuery 获取跨域XML(RSS)数据的相关总结分析
2016/05/18 Javascript
深入理解jQuery之防止冒泡事件
2016/05/24 Javascript
JavaScript自定义浏览器滚动条兼容IE、 火狐和chrome
2017/01/05 Javascript
js实现无缝滚动图
2017/02/22 Javascript
angularJs-$http实现百度搜索时的动态下拉框示例
2018/02/27 Javascript
vue 权限认证token的实现方法
2018/07/17 Javascript
Vue CLI 3.x 自动部署项目至服务器的方法
2019/04/02 Javascript
element-ui table组件如何使用render属性的实现
2019/11/04 Javascript
vue实现带过渡效果的下拉菜单功能
2020/02/19 Javascript
vue使用微信扫一扫功能的实现代码
2020/04/11 Javascript
浅谈javascript如何获取文件后缀名
2020/08/07 Javascript
[03:55]显微镜下的DOTA2特别篇——430灰烬之灵神级操作
2014/06/24 DOTA
python求众数问题实例
2014/09/26 Python
浅谈用Python实现一个大数据搜索引擎
2017/11/28 Python
python实现多线程行情抓取工具的方法
2018/02/28 Python
pyqt5实现俄罗斯方块游戏
2019/01/11 Python
django-filter和普通查询的例子
2019/08/12 Python
python图片二值化提高识别率代码实例
2019/08/24 Python
python被修饰的函数消失问题解决(基于wraps函数)
2019/11/04 Python
matplotlib 对坐标的控制,加图例注释的操作
2020/04/17 Python
html5+css3气泡组件的实现
2014/11/21 HTML / CSS
Java中实现多态的机制是什么?
2014/12/07 面试题
商务英语专业应届毕业生求职信
2013/10/28 职场文书
品牌转让协议书
2014/08/20 职场文书
资源环境与城乡规划管理专业自荐书
2014/09/26 职场文书
安阳殷墟导游词
2015/02/10 职场文书
售后服务质量承诺书
2015/04/29 职场文书
公司劳动纪律管理制度
2015/08/04 职场文书
《窃读记》教学反思
2016/02/18 职场文书
python必学知识之文件操作(建议收藏)
2021/05/30 Python
MySQL约束超详解
2021/09/04 MySQL