转至 https://www.cnblogs.com/dengqichang/p/10364455.html

  1. 一、搭建好项目的环境。
  2.  
  3. 二、根据ElementUI官网的自定义主题(http://element.eleme.io/#/zh-CN/component/custom-theme)来安装【主题生成工具】。
  4.  
  5. 首先安装「主题生成工具」,可以全局安装或者安装在当前项目下,推荐安装在项目里,方便别人 clone 项目时能直接安装依赖并启动,这里以全局安装做演示。
  6.  
  7. npm i element-theme -g
  8. 安装白垩主题,可以从 npm 安装或者从 GitHub 拉取最新代码。
  9.  
  10. # 从 npm
  11. npm i element-theme-chalk -D
  12.  
  13. # 从 GitHub
  14. npm i https://github.com/ElementUI/theme-chalk -D
  15. ¶初始化变量文件
  16. 主题生成工具安装成功后,如果全局安装可以在命令行里通过 et 调用工具,如果安装在当前目录下,需要通过 node_modules/.bin/et 访问到命令。执行 -i 初始化变量文件。默认输出到 element-variables.scss,当然你可以传参数指定文件输出目录。
  17.  
  18. et -i [可以自定义变量文件]
  19.  
  20. > Generator variables file
  21. 如果使用默认配置,执行后当前目录会有一个 element-variables.scss 文件。内部包含了主题所用到的所有变量,它们使用 SCSS 的格式定义。大致结构如下:
  22.  
  23. $--color-primary: #409EFF !default;
  24. $--color-primary-light-1: mix($--color-white, $--color-primary, 10%) !default; /* 53a8ff */
  25. $--color-primary-light-2: mix($--color-white, $--color-primary, 20%) !default; /* 66b1ff */
  26. $--color-primary-light-3: mix($--color-white, $--color-primary, 30%) !default; /* 79bbff */
  27. $--color-primary-light-4: mix($--color-white, $--color-primary, 40%) !default; /* 8cc5ff */
  28. $--color-primary-light-5: mix($--color-white, $--color-primary, 50%) !default; /* a0cfff */
  29. $--color-primary-light-6: mix($--color-white, $--color-primary, 60%) !default; /* b3d8ff */
  30. $--color-primary-light-7: mix($--color-white, $--color-primary, 70%) !default; /* c6e2ff */
  31. $--color-primary-light-8: mix($--color-white, $--color-primary, 80%) !default; /* d9ecff */
  32. $--color-primary-light-9: mix($--color-white, $--color-primary, 90%) !default; /* ecf5ff */
  33.  
  34. $--color-success: #67c23a !default;
  35. $--color-warning: #e6a23c !default;
  36. $--color-danger: #f56c6c !default;
  37. $--color-info: #909399 !default;
  38.  
  39. ...
  40. ¶修改变量
  41. 直接编辑 element-variables.scss 文件,例如修改主题色为红色。
  42.  
  43. $--color-primary: red;
  44. ¶编译主题
  45. 保存文件后,到命令行里执行 et 编译主题,如果你想启用 watch 模式,实时编译主题,增加 -w 参数;如果你在初始化时指定了自定义变量文件,则需要增加 -c 参数,并带上你的变量文件名
  46.  
  47. et
  48.  
  49. > build theme font
  50. > build element theme
  51. ¶引入自定义主题
  52. 默认情况下编译的主题目录是放在 ./theme 下,你可以通过 -o 参数指定打包目录。像引入默认主题一样,在代码里直接引用 theme/index.css 文件即可。
  53.  
  54. import '../theme/index.css'
  55. import ElementUI from 'element-ui'
  56. import Vue from 'vue'
  57.  
  58. Vue.use(ElementUI)
  59.  
  60. 三、在 element-variables.scss 文件里修改 $color-primary:#409EFF,即你想要的主题颜色。然后,执行主题编译命令生成主题(et),根目录会生成一个theme文件夹。

四、封装动态换肤色ThemePicker.vue组件。

  1. <template>
  2. <el-color-picker
  3. class="theme-picker"
  4. popper-class="theme-picker-dropdown"
  5. v-model="theme"
  6. :size="size">
  7. </el-color-picker>
  8. </template>
  9.  
  10. <script>
  11.  
  12. const version = require('element-ui/package.json').version // element-ui version from node_modules
  13. const ORIGINAL_THEME = '#409EFF' // default color
  14. export default {
  15. name: 'ThemePicker',
  16. props: {
  17. default: { // 初始化主题,可由外部传入
  18. type: String,
  19. //default: '#EB815B'
  20. default: ""+localStorage.getItem("tremePackers")+""
  21. },
  22. size: { // 初始化主题,可由外部传入
  23. type: String,
  24. default: 'small'
  25. }
  26. },
  27. data() {
  28. return {
  29. chalk: '', // content of theme-chalk css
  30. theme: ORIGINAL_THEME,
  31. showSuccess: true, // 是否弹出换肤成功消息
  32. }
  33. },
  34. mounted() {
  35. if(this.default != null) {
  36. this.theme = this.default
  37. this.$emit('onThemeChange', this.theme)
  38. this.showSuccess = false
  39. }
  40. },
  41. watch: {
  42. theme(val, oldVal) {
  43. if (typeof val !== 'string') return
  44. const themeCluster = this.getThemeCluster(val.replace('#', ''))
  45. const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
  46. const getHandler = (variable, id) => {
  47. return () => {
  48. const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))
  49. const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster)
  50.  
  51. let styleTag = document.getElementById(id)
  52. if (!styleTag) {
  53. styleTag = document.createElement('style')
  54. styleTag.setAttribute('id', id)
  55. document.head.appendChild(styleTag)
  56. }
  57. styleTag.innerText = newStyle
  58. }
  59. }
  60.  
  61. const chalkHandler = getHandler('chalk', 'chalk-style')
  62.  
  63. if (!this.chalk) {
  64. const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`
  65. this.getCSSString(url, chalkHandler, 'chalk')
  66. } else {
  67. chalkHandler()
  68. }
  69.  
  70. const styles = [].slice.call(document.querySelectorAll('style'))
  71. .filter(style => {
  72. const text = style.innerText
  73. return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)
  74. })
  75. styles.forEach(style => {
  76. const { innerText } = style
  77. if (typeof innerText !== 'string') return
  78. style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)
  79. })
  80.  
  81. // 响应外部操作
  82. this.$emit('onThemeChange', val)
  83. //存入localStorage
  84. localStorage.setItem('tremePackers',val);
  85. if(this.showSuccess) {
  86. this.$message({
  87. message: '换肤成功',
  88. type: 'success'
  89. })
  90. } else {
  91. this.showSuccess = true
  92. }
  93. }
  94. },
  95. methods: {
  96. updateStyle(style, oldCluster, newCluster) {
  97. let newStyle = style
  98. oldCluster.forEach((color, index) => {
  99. newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
  100. })
  101. return newStyle
  102. },
  103.  
  104. getCSSString(url, callback, variable) {
  105. const xhr = new XMLHttpRequest()
  106. xhr.onreadystatechange = () => {
  107. if (xhr.readyState === 4 && xhr.status === 200) {
  108. this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
  109. callback()
  110. }
  111. }
  112. xhr.open('GET', url)
  113. xhr.send()
  114. },
  115.  
  116. getThemeCluster(theme) {
  117. const tintColor = (color, tint) => {
  118. let red = parseInt(color.slice(0, 2), 16)
  119. let green = parseInt(color.slice(2, 4), 16)
  120. let blue = parseInt(color.slice(4, 6), 16)
  121.  
  122. if (tint === 0) { // when primary color is in its rgb space
  123. return [red, green, blue].join(',')
  124. } else {
  125. red += Math.round(tint * (255 - red))
  126. green += Math.round(tint * (255 - green))
  127. blue += Math.round(tint * (255 - blue))
  128.  
  129. red = red.toString(16)
  130. green = green.toString(16)
  131. blue = blue.toString(16)
  132.  
  133. return `#${red}${green}${blue}`
  134. }
  135. }
  136.  
  137. const shadeColor = (color, shade) => {
  138. let red = parseInt(color.slice(0, 2), 16)
  139. let green = parseInt(color.slice(2, 4), 16)
  140. let blue = parseInt(color.slice(4, 6), 16)
  141.  
  142. red = Math.round((1 - shade) * red)
  143. green = Math.round((1 - shade) * green)
  144. blue = Math.round((1 - shade) * blue)
  145.  
  146. red = red.toString(16)
  147. green = green.toString(16)
  148. blue = blue.toString(16)
  149.  
  150. return `#${red}${green}${blue}`
  151. }
  152.  
  153. const clusters = [theme]
  154. for (let i = 0; i <= 9; i++) {
  155. clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
  156. }
  157. clusters.push(shadeColor(theme, 0.1))
  158. return clusters
  159. }
  160. }
  161. }
  162. </script>
  163.  
  164. <style>
  165. .theme-picker .el-color-picker__trigger {
  166. vertical-align: middle;
  167. }
  168.  
  169. .theme-picker-dropdown .el-color-dropdown__link-btn {
  170. display: none;
  171. }
  172. </style>

五、直接在组件中引用

六、换肤效果测试。

vue+ element 动态换肤的更多相关文章

  1. element-ui 动态换肤

    1.在安装好 element-ui@2.x 以后,首先安装sass-loader npm i sass-loader node-sass -D 2.安装 element-theme npm i ele ...

  2. hybird之web动态换肤实现

    前言 最近在重构个hybird(原生的壳包着Web页面)的UI框架,进行到了做换肤功能的阶段,所以这里是我思考的解决的方法. 预想 目前实现换肤的功能无非就两种做法. 1.写几个皮肤文件,然后切换使用 ...

  3. CocoStudio基础教程(4)骨骼动画的动态换肤

    1.概述 游戏中人物的状态会发生改变,而这种改变通常要通过局部的变化来表现出来.比如获得一件装备后人物形象的改变,或者战斗中武器.防具的损坏等.这些变化的实现就要通过动态换肤来实现. 2.运行到程序 ...

  4. duilib入门之贴图描述、类html文本描述、动态换肤、Dll插件、资源打包

    转载自duilib入门文档 贴图描述: Duilib的表现力丰富很大程度上得益于贴图描述的简单强大.Duilib的贴图描述分为简单模式和复杂模式两种. 简单模式使用文件名做为贴图描述内容,在这种方式下 ...

  5. Cocos2d-x 3.0 cocostudio骨骼动画的动态换肤

    概述 游戏中人物的状态会发生改变,而这种改变通常要通过局部的变化来表现出来.比如获得一件装备后人物形象的改变,或者战斗中武器.防具的损坏等.这些变化的实现就要通过动态换肤来实现.在接下来的这个Demo ...

  6. Android动态换肤(二、apk免安装插件方式)

    在上一篇文章Android动态换肤(一.应用内置多套皮肤)中,我们了解到,动态换肤无非就是调用view的setBackgroundResource(R.drawable.id)等方法设置控件的背景或者 ...

  7. Android动态换肤(一、应用内置多套皮肤)

    动态换肤在很多android应用中都有使用,用户根据自己的喜好设置皮肤主题,可以增强用户使用应用的舒适度. Android换肤可以分为很多种,它们从使用方式,用户体验以及项目框架设计上体现了明显的差异 ...

  8. WPF之动态换肤

    原文:WPF之动态换肤 如何实现换肤呢,对于复杂的换肤操作,如,更换按钮样式.窗口样式等,我们需要写多个资源字典来表示不同的皮肤,通过动态加载不同的资源字典来实现换肤的效果:对于简单的换肤操作,如更改 ...

  9. vue+element 动态表单验证

    公司最近的项目有个添加动态表单的需求,总结一下我在表单验证上遇到的一些坑. 如图是功能的需求,这个功能挺好实现的,但是表单验证真是耗费了我一些功夫. vue+element在表单验证上有一些限制,必须 ...

随机推荐

  1. [Java复习] 集合框架 Collection

    Q1 Collection java的集合以及集合之间的继承关系? 数组和链表的区别? 固定长度,连续内存,不能扩展,随机访问快,插入删除慢.链表相反 List, Set, Map的区别? List, ...

  2. Python--多任务(多进程,多线程,协程)

    1.单核CPU实现“多任务”:(注意:这里的多任务假的,是轮训执行多个任务一段时间) 1)时间片轮转 2)优先级调度算法 2.并行:真的多任务执行(CPU核数>=任务数):即在某个时刻点上,有多 ...

  3. python matlab 带包实现全排列

    >> A=[2,5,7];perms(A) ans = 7 5 2 7 2 5 5 7 2 5 2 7 2 7 5 2 5 7 >> perms(1:4) ans = 4 3 ...

  4. redis 3.2.5单机版安装、使用、systemctl管理Redis启动、停止、开机启动

    参照地址 http://www.mamicode.com/info-detail-1488639.html 前提:防火墙安装,然后打开端口,设置开机启动 一.redis源码安装 [root@host- ...

  5. C# CRC16 modbus

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  6. Django:(04)状态保持和验证

    一.Cookie 特点 ​ Cookie是由服务器(网站)生成的,存储在浏览器端的 键值对数据(通常经过加密) 在响应请求时,服务器会把生成 Cookie数据 发给浏览器,浏览器会自动保存 (前提:浏 ...

  7. SQL易错锦集

    1.LIMIT 语句 分页查询是最常用的场景之一,但也通常也是最容易出问题的地方.比如对于下面简单的语句,一般 DBA 想到的办法是在 type, name, create_time 字段上加组合索引 ...

  8. 并查集 --cogs456 岛国

    题目链接:http://cogs.pro:8081/cogs/problem/problem.php?pid=pNyNQiqge 思路: 基础是并查集,将两个相邻的岛算作一个集合,每次若合并成功,则N ...

  9. Python os 使用

    python os 使用 1. 获取文件所在路径 import os os.path.dirname(__file__)  获取当前文件的所在路径 print (os.path.dirname(os. ...

  10. OpenCV 2.4.8 or OpenCV 2.4.9组件结构全解析

    之前啃了不少OpenCV的官方文档,发现如果了解了一些OpenCV整体的模块架构后,再重点学习自己感兴趣的部分的话,就会有一览众山小的感觉,于是,就决定写出这篇文章,作为启程OpenCV系列博文的第二 ...