详解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 相关文章推荐
js自定义事件及事件交互原理概述(一)
Feb 01 Javascript
Javascript的setTimeout()使用闭包特性时需要注意的问题
Sep 23 Javascript
JavaScript中的对象序列化介绍
Dec 30 Javascript
javascript高级编程之函数表达式 递归和闭包函数
Nov 29 Javascript
AngularJS Module方法详解
Dec 08 Javascript
禁用backspace网页回退功能的实现代码
Nov 15 Javascript
百度地图JavascriptApi Marker平滑移动及车头指向行径方向
Mar 13 Javascript
JS+Ajax实现百度智能搜索框
Aug 04 Javascript
JS中正则表达式要注意lastIndex属性
Aug 08 Javascript
详解vue-router 命名路由和命名视图
Jun 01 Javascript
JS前端知识点offset,scroll,client,冒泡,事件对象的应用整理总结
Jun 27 Javascript
Vue根据条件添加click事件的方式
Nov 09 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
2020年4月新番动漫目录 官方宣布4月播出的作品一览
2020/03/08 日漫
如何使用PHP给图片加水印
2016/10/12 PHP
文字幻灯片
2006/06/26 Javascript
B/S开发中常用javaScript技术与代码
2007/03/09 Javascript
JQuery 常用方法基础教程
2009/02/06 Javascript
jquery select操作的日期联动实现代码
2009/12/06 Javascript
ASP.NET jQuery 实例12 通过使用jQuery validation插件简单实现用户注册页面验证功能
2012/02/03 Javascript
在浏览器中实现图片粘贴的jQuery插件-- pasteimg使用指南
2014/12/29 Javascript
基于jQuery实现的美观星级评论打分组件代码
2015/10/30 Javascript
超详细的javascript数组方法汇总
2015/11/21 Javascript
JS实现鼠标框选效果完整实例
2016/06/20 Javascript
Bootstrap中文本框的宽度变窄并且加入一副验证码图片的实现方法
2016/06/23 Javascript
JS实现的手机端精简幻灯片效果
2016/09/05 Javascript
微信小程序 progress组件详解及实例代码
2016/10/25 Javascript
ES6(ECMAScript 6)新特性之模板字符串用法分析
2017/04/01 Javascript
基于JavaScript实现飘落星星特效
2017/08/10 Javascript
微信小程序分享功能之按钮button 边框隐藏和点击隐藏
2018/06/14 Javascript
理顺8个版本vue的区别(小结)
2018/09/17 Javascript
微信小程序中weui用法解析
2019/10/21 Javascript
webpack+express实现文件精确缓存的示例代码
2020/06/11 Javascript
[53:15]2018DOTA2亚洲邀请赛3月29日 小组赛A组 KG VS OG
2018/03/30 DOTA
使用Python下载Bing图片(代码)
2013/11/07 Python
Python实现两款计算器功能示例
2017/12/19 Python
Python中is和==的区别详解
2018/11/15 Python
Python3+Pycharm+PyQt5环境搭建步骤图文详解
2019/05/29 Python
pandas如何处理缺失值
2019/07/31 Python
Python的互斥锁与信号量详解
2019/09/12 Python
canvas实现烟花的示例代码
2020/01/16 HTML / CSS
英国足球店:UK Soccer Shop
2017/11/19 全球购物
人力资源部经理岗位职责规定
2014/02/23 职场文书
投资意向书范本
2014/04/01 职场文书
经典团队口号大全
2014/06/21 职场文书
大学校园招聘会感想
2015/08/10 职场文书
Nginx同一个域名配置多个项目的实现方法
2021/03/31 Servers
MySQL中InnoDB存储引擎的锁的基本使用教程
2021/05/26 MySQL
「女孩的钓鱼慢活」全新版权绘公布
2022/03/21 日漫