前言

提示:动态切换主题使用的是css3的var函数现实

示例:切换--main-bg-color的值,使用<div style="--main-bg-color:red"> </div> 那么当前标签下的所有节点使用到当前变量的都会发生变化

:root {--main-bg-color: coral;
}#div1 {background-color: var(--main-bg-color);
}#div2 {background-color: var(--main-bg-color);
}

一、elementui css变量都有哪些

通过浏览器检查,发现element ui库的变量

二、如何修改这些变量

提示: 众所周知css是从上往下执行,如果我们可以在hand标签里最后一个添加一个style标签,是不是就可以重写掉element ui的变量

1.添加在head标签里面添加style标签(在main.ts添加如下代码)

代码如下(示例):

代码如下:

const style = document.createElement("style");
style.innerText = ":root{--el-color-primary:red}";
document.head.appendChild(style);

可以发现elementui的主色调已经被我们替换为红色

三、如何动态修改颜色

前言:

  1. 查看element.sass源码可以发现,一个primary样式,可以生成多个渐变色

    $types: primary, success, warning, danger, error, info;
    @each $type in $types {@for $i from 1 through 9 {@include set-color-mix-level($type, $i, 'light', $color-white);}
    }// --el-color-primary-dark-2
    @each $type in $types {@include set-color-mix-level($type, 2, 'dark', $color-black);
    }

不难发现 --el-color-primary-dark-2变量 是当前primary颜色跟黑色混和百分之20生成的颜色

所以设置一个primary的颜色会生成会生成1-9的和白色混的渐变色,生产一个百分之20的和黑色混的颜色

那么我们的变量就分为俩种:

推断类型: 通过一个主色调变量,生成n个渐变色

键值类型:一个变量对应一个值

直接上代码

定义数据类型

interface ThemeSetting {/***element-ui Namespace*/namespace: string;/*** 数据分隔符*/division: string;/*** 前缀*/startDivision: string;/*** 颜色外推设置*/colorInferSetting: ColorInferSetting;
}/*** 颜色混和设置*/
interface ColorInferSetting {/*** 与白色混*/light: Array<number>;/*** 与黑色混*/dark: Array<number>;/*** 类型*/type: string;
}/*** 平滑数据*/
interface KeyValueData {[propName: string]: string;
}
type UpdateInferData = KeyValueData;type UpdateKeyValueData = KeyValueData;
/***平滑数据*/
interface InferData {/*** 设置*/setting?: ColorInferSetting | any;/*** 健*/key: string;/*** 值*/value: string;
}export type {KeyValueData,InferData,ThemeSetting,UpdateInferData,UpdateKeyValueData,
};

定义配置数据

import type { ThemeSetting } from "./type";
const setting: ThemeSetting = {namespace: "el",division: "-",startDivision: "--",colorInferSetting: {light: [3, 5, 7, 8, 9],dark: [2],type: "color",},
};
export default setting;

定义默认推断数据

import type { InferData } from "./type";
const inferDatas: Array<InferData> = [];
export default inferDatas;

定义默认键值数据

import type { KeyValueData } from "./type";
const keyValueData: KeyValueData = {"menu-item-height": "56px",
};
export default keyValueData;

编写动态修改主题代码

import type {ThemeSetting,InferData,KeyValueData,UpdateInferData,UpdateKeyValueData,
} from "./type";
import tinycolor from "@ctrl/tinycolor";declare global {interface ChildNode {innerText: string;}
}
class Theme {/*** 主题设置*/themeSetting: ThemeSetting;/*** 键值数据*/keyValue: KeyValueData;/*** 外推数据*/inferDatas: Array<InferData>;/***是否是第一次初始化*/isFirstWriteStyle: boolean;/*** 混色白*/colorWhite: string;/*** 混色黑*/colorBlack: string;constructor(themeSetting: ThemeSetting,keyValue: KeyValueData,inferDatas: Array<InferData>) {this.themeSetting = themeSetting;this.keyValue = keyValue;this.inferDatas = inferDatas;this.isFirstWriteStyle = true;this.colorWhite = "#ffffff";this.colorBlack = "#000000";}/*** 拼接* @param setting 主题设置* @param names   需要拼接的所有值* @returns       拼接后的数据*/getVarName = (setting: ThemeSetting, ...names: Array<string>) => {return (setting.startDivision +setting.namespace +setting.division +names.join(setting.division));};/*** 转换外推数据* @param setting      主题设置对象* @param inferData    外推数据* @returns*/mapInferMainStyle = (setting: ThemeSetting, inferData: InferData) => {const key: string = this.getVarName(setting,inferData.setting? inferData.setting.type: setting.colorInferSetting.type,inferData.key);return {[key]: inferData.value,...this.mapInferDataStyle(setting, inferData),};};/*** 转换外推数据* @param setting    设置* @param inferDatas 外推数据*/mapInferData = (setting: ThemeSetting, inferDatas: Array<InferData>) => {return inferDatas.map((itemData) => {return this.mapInferMainStyle(setting, itemData);}).reduce((pre, next) => {return { ...pre, ...next };}, {});};/*** 转换外推数据* @param setting      主题设置对象* @param inferData    外推数据* @returns*/mapInferDataStyle = (setting: ThemeSetting, inferData: InferData) => {const inferSetting = inferData.setting? inferData.setting: setting.colorInferSetting;if (inferSetting.type === "color") {return Object.keys(inferSetting).map((key: string) => {if (key === "light" || key === "dark") {return inferSetting[key].map((l) => {const varName = this.getVarName(setting,inferSetting.type,inferData.key,key,l.toString());return {[varName]: tinycolor(inferData.value).mix(key === "light" ? this.colorWhite : this.colorBlack,l * 10).toHexString(),};}).reduce((pre, next) => {return { ...pre, ...next };}, {});}return {};}).reduce((pre, next) => {return { ...pre, ...next };}, {});}return {};};/**** @param themeSetting 主题设置* @param keyValueData 键值数据* @returns            映射后的键值数据*/mapKeyValue = (themeSetting: ThemeSetting, keyValueData: KeyValueData) => {return Object.keys(keyValueData).map((key: string) => {return {[this.updateKeyBySetting(key, themeSetting)]: keyValueData[key],};}).reduce((pre, next) => {return { ...pre, ...next };}, {});};/*** 根据配置文件修改Key* @param key          key* @param themeSetting 主题设置* @returns*/updateKeyBySetting = (key: string, themeSetting: ThemeSetting) => {return key.startsWith(themeSetting.startDivision)? key: key.startsWith(themeSetting.namespace)? themeSetting.startDivision + key: key.startsWith(themeSetting.division)? themeSetting.startDivision + themeSetting.namespace: themeSetting.startDivision +themeSetting.namespace +themeSetting.division +key;};/**** @param setting    主题设置* @param keyValue   主题键值对数据* @param inferDatas 外推数据* @returns 合并后的键值对数据*/tokeyValueStyle = () => {return {...this.mapInferData(this.themeSetting, this.inferDatas),...this.mapKeyValue(this.themeSetting, this.keyValue),};};/*** 将keyValue对象转换为S* @param keyValue* @returns*/toString = (keyValue: KeyValueData) => {const inner = Object.keys(keyValue).map((key: string) => {return key + ":" + keyValue[key] + ";";}).join("");return `@charset "UTF-8";:root{${inner}}`;};/**** @param elNewStyle 新的变量样式*/writeNewStyle = (elNewStyle: string) => {if (this.isFirstWriteStyle) {const style = document.createElement("style");style.innerText = elNewStyle;document.head.appendChild(style);this.isFirstWriteStyle = false;} else {if (document.head.lastChild) {document.head.lastChild.innerText = elNewStyle;}}};/*** 修改数据并且写入dom* @param updateInferData   平滑数据修改* @param updateKeyvalueData keyValue数据修改*/updateWrite = (updateInferData?: UpdateInferData,updateKeyvalueData?: UpdateKeyValueData) => {this.update(updateInferData, updateKeyvalueData);const newStyle = this.tokeyValueStyle();const newStyleString = this.toString(newStyle);this.writeNewStyle(newStyleString);};/*** 修改数据* @param inferData* @param keyvalueData*/update = (updateInferData?: UpdateInferData,updateKeyvalueData?: UpdateKeyValueData) => {if (updateInferData) {this.updateInferData(updateInferData);}if (updateKeyvalueData) {this.updateOrCreateKeyValueData(updateKeyvalueData);}};/*** 修改外推数据 外推数据只能修改,不能新增* @param inferData*/updateInferData = (updateInferData: UpdateInferData) => {Object.keys(updateInferData).forEach((key) => {const findInfer = this.inferDatas.find((itemInfer) => {return itemInfer.key === key;});if (findInfer) {findInfer.value = updateInferData[key];} else {this.inferDatas.push({ key, value: updateInferData[key] });}});};/*** 修改KeyValue数据* @param keyvalueData keyValue数据*/updateOrCreateKeyValueData = (updateKeyvalueData: UpdateKeyValueData) => {Object.keys(updateKeyvalueData).forEach((key) => {const newKey = this.updateKeyBySetting(key, this.themeSetting);this.keyValue[newKey] = updateKeyvalueData[newKey];});};
}export default Theme;

使用

// 引入主题对象
import Theme from "./theme";
// 引入默认推断数据
import inferDatas from "./theme/inferDatas";
// 引入默认keyValue数据
import keyValueData from "./theme/keyValueData";
// 引入设置对象
import setting from "./theme/setting";
const app = createApp(App);
// 创建主题对象
const theme = new Theme(setting, keyValueData, inferDatas);
// 将主题对象放到全局变量中
app.config.globalProperties.theme = theme;

其他组件使用

import { reactive, getCurrentInstance } from "vue";
import type { ComponentInternalInstance } from "vue";
const { appContext } = getCurrentInstance() as ComponentInternalInstance;
const theme = appContext.config.globalProperties.theme;
theme.updateWrite({ primary: form.themeColor });

API

- 修改推断数据

theme.updateWrite({primary: "#409eff",success: "#67c23a",warning: "#e6a23c",danger: "#f56c6c",error: "#f56c6c",info: "#909399",});

- 修改键值类型数据

theme.updateWrite(undefined, {"--el-menu-active-color": "red","--el-menu-bg-color": "pink","--el-menu-item-height": "22px",});

- 一起修改

theme.updateWrite({primary: "#409eff",success: "#67c23a",warning: "#e6a23c",danger: "#f56c6c",error: "#f56c6c",info: "#909399",},{"--el-menu-active-color": "red","--el-menu-bg-color": "pink","--el-menu-item-height": "22px",});

总结:

主题数据可以存储在数据库中,通过接口查询后调用函数修改即可完成动态主题

element如何动态切换主题(vite+vue+ts+elementPlus)相关推荐

  1. vue动态发布到线上_vue在线动态切换主题色方案

    主要原理是利用webpack插件webpack-theme-color-replacer提取相关颜色css然后根据配置动态生成替换的css 具体实现步骤如下: 1.添加webpack插件,新建文件we ...

  2. vue在线动态切换主题色方案

    主要原理是利用webpack插件webpack-theme-color-replacer提取相关颜色css然后根据配置动态生成替换的css,具体实现步骤如下: 1.添加webpack插件,新建文件we ...

  3. vue动态切换css文件_vue在线动态切换主题色方案

    主要原理是利用webpack插件webpack-theme-color-replacer提取相关颜色css然后根据配置动态生成替换的css 具体实现步骤如下: 1.添加webpack插件,新建文件we ...

  4. Android动态切换主题

    软件换肤从功能上可以划分三种: 1) 软件内置多个皮肤,不可由用户增加或修改: 最低的自由度,软件实现相对于后两种最容易. 2) 官方提供皮肤供下载,用户可以使用下载的皮肤: 用户可选择下载自己喜欢的 ...

  5. 直播短视频系统开发,动态切换主题色

    直播短视频系统开发,动态切换主题色相关的代码: 点击按钮变量存储切换状态: override fun onClick(v: View?) {when (v?.id) {R.id.btn_theme1 ...

  6. 一对一直播app源码,Aandroid动态切换主题色

    一对一直播app源码,Aandroid动态切换主题色实现的相关代码 点击按钮变量存储切换状态: override fun onClick(v: View?) {when (v?.id) {R.id.b ...

  7. ECharts实现动态切换主题样式

    ECharts是百度开源的一个JS数据可视化库.通过颜色主题可以轻松实现不同颜色样式的修改,也可以通过调色盘.直接样式设置.高亮样式等方法实现. ECharts4 开始,除了一贯的默认主题外,新内置了 ...

  8. vite+vue3+ts+element-plus项目搭建--超详细

    vite+vue3+ts+element-plus项目搭建–超详细 vite 作用 快速的冷启动:不需要等待打包操作: 即时的热模块更新:替换性能和模块数量的解耦让更新飞起: 真正的按需编译:不再等待 ...

  9. 【Vue 开发实战】实战篇 # 42:如何定制主题及动态切换主题

    说明 [Vue 开发实战]学习笔记. vuecli3 配置 module.exports = {css: {loaderOptions: {less: {modifyVars: {'primary-c ...

最新文章

  1. 理论应用实例水杯_PID理解起来很难?系统讲解PID控制及参数调节,理论加实际才好...
  2. Gradle构建中:No cached version available for offline mode解决方案
  3. 自然语言处理中的模式(模式1.概率化模式)
  4. lc滤波电路电感电容值选择_滤波电容如何选择
  5. 与缓存有关的http-header
  6. [Android Samples视频系列之ApiDemos] App-Activity-Recreate
  7. Linux 如何打开pyo文件,Python的文件类型
  8. 雅虎前端优化35条军规
  9. python导入鸢尾花数据集_决策树分类鸢尾花数据集python实现
  10. Spring Cloud和Spring Boot高级视频
  11. 你的账户配置为阻止使用计算机,Win10打开软件提示为了对电脑进行保护,已经阻止此应用解决方法...
  12. 计算机网络课后习题概略
  13. 怎么提高国外服务器速度?
  14. 【2011年全国试题3】已知循环队列存储在一维数组A[0…n-1],且队列非空时,front和rear分别指向队头元素和队尾元素。若初始时队列为空,且
  15. Python拆分PPT文件的方法
  16. 喜讯|星舆科技获得CMMI 3级认证,研发能力获国际认可!
  17. 建立dblink(database link)
  18. 用友U8+助力服装织造企业信息化建设 用友ERP 用友T+ 上海杰然软件
  19. aw2013驱动分析
  20. quickAction

热门文章

  1. 无机EcotionPOSS101缩水甘油醚氧丙基笼状聚倍半硅氧烷POSS的沸点是多少
  2. windows防火墙无法更改某些设置 错误代码0X8007
  3. 在 Surfer 中对具有不同网格几何形状的网格使用 Grid Math 和 Grid Volume
  4. Neo4j入门篇-Neo4j安装
  5. 初学Android——闪光灯当做手电筒使用
  6. java 文字生成图片
  7. 经典布局——圣杯布局
  8. python课件_python展示ppt
  9. Apex运行时报错提示“easy anti-cheat”“Game Security Violation Detected(#0000000D)[xxx.exe]“ 问题解决方案
  10. 华为手机还有这么好用的翻译功能!说话就能语音翻译,高效又便捷