vue+ element 动态换肤
转至 https://www.cnblogs.com/dengqichang/p/10364455.html
- 一、搭建好项目的环境。
- 二、根据ElementUI官网的自定义主题(http://element.eleme.io/#/zh-CN/component/custom-theme)来安装【主题生成工具】。
- 首先安装「主题生成工具」,可以全局安装或者安装在当前项目下,推荐安装在项目里,方便别人 clone 项目时能直接安装依赖并启动,这里以全局安装做演示。
- npm i element-theme -g
- 安装白垩主题,可以从 npm 安装或者从 GitHub 拉取最新代码。
- # 从 npm
- npm i element-theme-chalk -D
- # 从 GitHub
- npm i https://github.com/ElementUI/theme-chalk -D
- ¶初始化变量文件
- 主题生成工具安装成功后,如果全局安装可以在命令行里通过 et 调用工具,如果安装在当前目录下,需要通过 node_modules/.bin/et 访问到命令。执行 -i 初始化变量文件。默认输出到 element-variables.scss,当然你可以传参数指定文件输出目录。
- et -i [可以自定义变量文件]
- > ✔ Generator variables file
- 如果使用默认配置,执行后当前目录会有一个 element-variables.scss 文件。内部包含了主题所用到的所有变量,它们使用 SCSS 的格式定义。大致结构如下:
- $--color-primary: #409EFF !default;
- $--color-primary-light-1: mix($--color-white, $--color-primary, 10%) !default; /* 53a8ff */
- $--color-primary-light-2: mix($--color-white, $--color-primary, 20%) !default; /* 66b1ff */
- $--color-primary-light-3: mix($--color-white, $--color-primary, 30%) !default; /* 79bbff */
- $--color-primary-light-4: mix($--color-white, $--color-primary, 40%) !default; /* 8cc5ff */
- $--color-primary-light-5: mix($--color-white, $--color-primary, 50%) !default; /* a0cfff */
- $--color-primary-light-6: mix($--color-white, $--color-primary, 60%) !default; /* b3d8ff */
- $--color-primary-light-7: mix($--color-white, $--color-primary, 70%) !default; /* c6e2ff */
- $--color-primary-light-8: mix($--color-white, $--color-primary, 80%) !default; /* d9ecff */
- $--color-primary-light-9: mix($--color-white, $--color-primary, 90%) !default; /* ecf5ff */
- $--color-success: #67c23a !default;
- $--color-warning: #e6a23c !default;
- $--color-danger: #f56c6c !default;
- $--color-info: #909399 !default;
- ...
- ¶修改变量
- 直接编辑 element-variables.scss 文件,例如修改主题色为红色。
- $--color-primary: red;
- ¶编译主题
- 保存文件后,到命令行里执行 et 编译主题,如果你想启用 watch 模式,实时编译主题,增加 -w 参数;如果你在初始化时指定了自定义变量文件,则需要增加 -c 参数,并带上你的变量文件名
- et
- > ✔ build theme font
- > ✔ build element theme
- ¶引入自定义主题
- 默认情况下编译的主题目录是放在 ./theme 下,你可以通过 -o 参数指定打包目录。像引入默认主题一样,在代码里直接引用 theme/index.css 文件即可。
- import '../theme/index.css'
- import ElementUI from 'element-ui'
- import Vue from 'vue'
- Vue.use(ElementUI)
- 三、在 element-variables.scss 文件里修改 $–color-primary:#409EFF,即你想要的主题颜色。然后,执行主题编译命令生成主题(et),根目录会生成一个theme文件夹。
四、封装动态换肤色ThemePicker.vue组件。
- <template>
- <el-color-picker
- class="theme-picker"
- popper-class="theme-picker-dropdown"
- v-model="theme"
- :size="size">
- </el-color-picker>
- </template>
- <script>
- const version = require('element-ui/package.json').version // element-ui version from node_modules
- const ORIGINAL_THEME = '#409EFF' // default color
- export default {
- name: 'ThemePicker',
- props: {
- default: { // 初始化主题,可由外部传入
- type: String,
- //default: '#EB815B'
- default: ""+localStorage.getItem("tremePackers")+""
- },
- size: { // 初始化主题,可由外部传入
- type: String,
- default: 'small'
- }
- },
- data() {
- return {
- chalk: '', // content of theme-chalk css
- theme: ORIGINAL_THEME,
- showSuccess: true, // 是否弹出换肤成功消息
- }
- },
- mounted() {
- if(this.default != null) {
- this.theme = this.default
- this.$emit('onThemeChange', this.theme)
- this.showSuccess = false
- }
- },
- watch: {
- theme(val, oldVal) {
- if (typeof val !== 'string') return
- const themeCluster = this.getThemeCluster(val.replace('#', ''))
- const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
- const getHandler = (variable, id) => {
- return () => {
- const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))
- const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster)
- let styleTag = document.getElementById(id)
- if (!styleTag) {
- styleTag = document.createElement('style')
- styleTag.setAttribute('id', id)
- document.head.appendChild(styleTag)
- }
- styleTag.innerText = newStyle
- }
- }
- const chalkHandler = getHandler('chalk', 'chalk-style')
- if (!this.chalk) {
- const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`
- this.getCSSString(url, chalkHandler, 'chalk')
- } else {
- chalkHandler()
- }
- const styles = [].slice.call(document.querySelectorAll('style'))
- .filter(style => {
- const text = style.innerText
- return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)
- })
- styles.forEach(style => {
- const { innerText } = style
- if (typeof innerText !== 'string') return
- style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)
- })
- // 响应外部操作
- this.$emit('onThemeChange', val)
- //存入localStorage
- localStorage.setItem('tremePackers',val);
- if(this.showSuccess) {
- this.$message({
- message: '换肤成功',
- type: 'success'
- })
- } else {
- this.showSuccess = true
- }
- }
- },
- methods: {
- updateStyle(style, oldCluster, newCluster) {
- let newStyle = style
- oldCluster.forEach((color, index) => {
- newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
- })
- return newStyle
- },
- getCSSString(url, callback, variable) {
- const xhr = new XMLHttpRequest()
- xhr.onreadystatechange = () => {
- if (xhr.readyState === 4 && xhr.status === 200) {
- this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
- callback()
- }
- }
- xhr.open('GET', url)
- xhr.send()
- },
- getThemeCluster(theme) {
- const tintColor = (color, tint) => {
- let red = parseInt(color.slice(0, 2), 16)
- let green = parseInt(color.slice(2, 4), 16)
- let blue = parseInt(color.slice(4, 6), 16)
- if (tint === 0) { // when primary color is in its rgb space
- return [red, green, blue].join(',')
- } else {
- red += Math.round(tint * (255 - red))
- green += Math.round(tint * (255 - green))
- blue += Math.round(tint * (255 - blue))
- red = red.toString(16)
- green = green.toString(16)
- blue = blue.toString(16)
- return `#${red}${green}${blue}`
- }
- }
- const shadeColor = (color, shade) => {
- let red = parseInt(color.slice(0, 2), 16)
- let green = parseInt(color.slice(2, 4), 16)
- let blue = parseInt(color.slice(4, 6), 16)
- red = Math.round((1 - shade) * red)
- green = Math.round((1 - shade) * green)
- blue = Math.round((1 - shade) * blue)
- red = red.toString(16)
- green = green.toString(16)
- blue = blue.toString(16)
- return `#${red}${green}${blue}`
- }
- const clusters = [theme]
- for (let i = 0; i <= 9; i++) {
- clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
- }
- clusters.push(shadeColor(theme, 0.1))
- return clusters
- }
- }
- }
- </script>
- <style>
- .theme-picker .el-color-picker__trigger {
- vertical-align: middle;
- }
- .theme-picker-dropdown .el-color-dropdown__link-btn {
- display: none;
- }
- </style>
五、直接在组件中引用
六、换肤效果测试。
vue+ element 动态换肤的更多相关文章
- element-ui 动态换肤
1.在安装好 element-ui@2.x 以后,首先安装sass-loader npm i sass-loader node-sass -D 2.安装 element-theme npm i ele ...
- hybird之web动态换肤实现
前言 最近在重构个hybird(原生的壳包着Web页面)的UI框架,进行到了做换肤功能的阶段,所以这里是我思考的解决的方法. 预想 目前实现换肤的功能无非就两种做法. 1.写几个皮肤文件,然后切换使用 ...
- CocoStudio基础教程(4)骨骼动画的动态换肤
1.概述 游戏中人物的状态会发生改变,而这种改变通常要通过局部的变化来表现出来.比如获得一件装备后人物形象的改变,或者战斗中武器.防具的损坏等.这些变化的实现就要通过动态换肤来实现. 2.运行到程序 ...
- duilib入门之贴图描述、类html文本描述、动态换肤、Dll插件、资源打包
转载自duilib入门文档 贴图描述: Duilib的表现力丰富很大程度上得益于贴图描述的简单强大.Duilib的贴图描述分为简单模式和复杂模式两种. 简单模式使用文件名做为贴图描述内容,在这种方式下 ...
- Cocos2d-x 3.0 cocostudio骨骼动画的动态换肤
概述 游戏中人物的状态会发生改变,而这种改变通常要通过局部的变化来表现出来.比如获得一件装备后人物形象的改变,或者战斗中武器.防具的损坏等.这些变化的实现就要通过动态换肤来实现.在接下来的这个Demo ...
- Android动态换肤(二、apk免安装插件方式)
在上一篇文章Android动态换肤(一.应用内置多套皮肤)中,我们了解到,动态换肤无非就是调用view的setBackgroundResource(R.drawable.id)等方法设置控件的背景或者 ...
- Android动态换肤(一、应用内置多套皮肤)
动态换肤在很多android应用中都有使用,用户根据自己的喜好设置皮肤主题,可以增强用户使用应用的舒适度. Android换肤可以分为很多种,它们从使用方式,用户体验以及项目框架设计上体现了明显的差异 ...
- WPF之动态换肤
原文:WPF之动态换肤 如何实现换肤呢,对于复杂的换肤操作,如,更换按钮样式.窗口样式等,我们需要写多个资源字典来表示不同的皮肤,通过动态加载不同的资源字典来实现换肤的效果:对于简单的换肤操作,如更改 ...
- vue+element 动态表单验证
公司最近的项目有个添加动态表单的需求,总结一下我在表单验证上遇到的一些坑. 如图是功能的需求,这个功能挺好实现的,但是表单验证真是耗费了我一些功夫. vue+element在表单验证上有一些限制,必须 ...
随机推荐
- [Java复习] 集合框架 Collection
Q1 Collection java的集合以及集合之间的继承关系? 数组和链表的区别? 固定长度,连续内存,不能扩展,随机访问快,插入删除慢.链表相反 List, Set, Map的区别? List, ...
- Python--多任务(多进程,多线程,协程)
1.单核CPU实现“多任务”:(注意:这里的多任务假的,是轮训执行多个任务一段时间) 1)时间片轮转 2)优先级调度算法 2.并行:真的多任务执行(CPU核数>=任务数):即在某个时刻点上,有多 ...
- 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 ...
- redis 3.2.5单机版安装、使用、systemctl管理Redis启动、停止、开机启动
参照地址 http://www.mamicode.com/info-detail-1488639.html 前提:防火墙安装,然后打开端口,设置开机启动 一.redis源码安装 [root@host- ...
- C# CRC16 modbus
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- Django:(04)状态保持和验证
一.Cookie 特点 Cookie是由服务器(网站)生成的,存储在浏览器端的 键值对数据(通常经过加密) 在响应请求时,服务器会把生成 Cookie数据 发给浏览器,浏览器会自动保存 (前提:浏 ...
- SQL易错锦集
1.LIMIT 语句 分页查询是最常用的场景之一,但也通常也是最容易出问题的地方.比如对于下面简单的语句,一般 DBA 想到的办法是在 type, name, create_time 字段上加组合索引 ...
- 并查集 --cogs456 岛国
题目链接:http://cogs.pro:8081/cogs/problem/problem.php?pid=pNyNQiqge 思路: 基础是并查集,将两个相邻的岛算作一个集合,每次若合并成功,则N ...
- Python os 使用
python os 使用 1. 获取文件所在路径 import os os.path.dirname(__file__) 获取当前文件的所在路径 print (os.path.dirname(os. ...
- OpenCV 2.4.8 or OpenCV 2.4.9组件结构全解析
之前啃了不少OpenCV的官方文档,发现如果了解了一些OpenCV整体的模块架构后,再重点学习自己感兴趣的部分的话,就会有一览众山小的感觉,于是,就决定写出这篇文章,作为启程OpenCV系列博文的第二 ...