UzumakiItachi
首页
  • JavaSript
  • Vue

    • Vue2
    • Vue3
  • React

    • React_18
  • WebPack
  • 浏览器相关
  • 工程化相关
  • 工作中遇到的问题以及解决方案
  • Git
  • 面试
  • 学习
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
  • 个人产出
  • 实用工具
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

UzumakiItachi

起风了,唯有努力生存。
首页
  • JavaSript
  • Vue

    • Vue2
    • Vue3
  • React

    • React_18
  • WebPack
  • 浏览器相关
  • 工程化相关
  • 工作中遇到的问题以及解决方案
  • Git
  • 面试
  • 学习
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
  • 个人产出
  • 实用工具
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • WebPack

  • 浏览器相关

  • 工程化相关

  • 工作中遇到的问题以及解决方案

    • 解决浏览器返回页面不刷新的问题
    • 前端如何下载文件流
    • uniapp APP端实现更新最新安装包
    • GitHub Actions Process completed with exit code 128 的解决方案
    • 保留文字输入的空格和换行
    • 缩放适配大屏页
    • 一次性加载n多张图片的性能优化方案
    • NOT-Cool 低代码页面架构思路
    • h5下载vcard快捷保存联系人信息
    • 结合elementui实现的动态主题
      • 前言
      • css变量
      • 具体做法
      • 拓展
    • 解决monorepo场景下子包作为依赖项在开发和生产暴露文件的问题
    • 给npm配置github令牌
    • 移动端电子印章解决方案
    • 小程序canvas绘制海报中遇到的一些坑
    • 超详细的虚拟列表实现过程
    • 小程序实现一个事件中心
    • 请求超时后如何优雅的重新请求
    • 超详细的大文件上传实现方案
    • 仿抖音短视频组件实现方案
    • swiper渲染大量数据的优化方案
    • 前端检测更新,自动刷新网页
  • Git

  • Vite

  • 一些小工具

  • 算法

  • 服务器

  • HTTP

  • 技术
  • 工作中遇到的问题以及解决方案
hanhanbuku
2023-09-05
目录

结合elementui实现的动态主题

# 前言

切换主题在管理系统中是一个常见的功能,本文将结合elementui来实现一个切换主题的功能

# css变量

css变量非常适合用于做样式的批量替换。elementui本身也是通过css变量来实现的不同主题的定制效果。对css变量不了解的可以自行了解一下,使用起来还是非常简单的。

# 具体做法

elementui使用了一下几个变量作为整个组件库的主色调和辅色

    --el-color-primary: #4165d7;
    --color-primary: #4165d7;
    --el-color-primary-light-1: #5474db;
    --el-color-primary-dark-1: #3b5bc2;
    --el-color-primary-light-2: #6784df;
    --el-color-primary-dark-2: #3451ac;
    --el-color-primary-light-3: #7a93e3;
    --el-color-primary-dark-3: #2e4797;
    --el-color-primary-light-4: #8da3e7;
    --el-color-primary-dark-4: #273d81;
    --el-color-primary-light-5: #a0b2eb;
    --el-color-primary-dark-5: #21336c;
    --el-color-primary-light-6: #b3c1ef;
    --el-color-primary-dark-6: #1a2856;
    --el-color-primary-light-7: #c6d1f3;
    --el-color-primary-dark-7: #131e40;
    --el-color-primary-light-8: #d9e0f7;
    --el-color-primary-dark-8: #0d142b;
    --el-color-primary-light-9: #ecf0fb;
    --el-color-primary-dark-9: #060a15;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

而我们要做的就是在切换主题后根据一个主色调计算出其他的辅色然后把这些个变量覆盖掉就好了。

计算色值的函数如下


function mix(color1: string, color2: string, weight: number) {
  weight = Math.max(Math.min(Number(weight), 1), 0)
  const r1 = parseInt(color1.substring(1, 3), 16)
  const g1 = parseInt(color1.substring(3, 5), 16)
  const b1 = parseInt(color1.substring(5, 7), 16)
  const r2 = parseInt(color2.substring(1, 3), 16)
  const g2 = parseInt(color2.substring(3, 5), 16)
  const b2 = parseInt(color2.substring(5, 7), 16)
  let r = Math.round(r1 * (1 - weight) + r2 * weight).toString(16)
  let g = Math.round(g1 * (1 - weight) + g2 * weight).toString(16)
  let b = Math.round(b1 * (1 - weight) + b2 * weight).toString(16)
  r = ('0' + (r || 0).toString(16)).slice(-2)
  g = ('0' + (g || 0).toString(16)).slice(-2)
  b = ('0' + (b || 0).toString(16)).slice(-2)
  return '#' + r + g + b
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

第一个参数传入我们的主色第二次参数可以传入黑色或白色作为辅色,这样就可以根据偏移量计算出基于主色演变出来的深色或浅色

剩下的事情就简单了,只需要在切换主题的时候拿到主色然后把生成出的颜色加入到html中就可以了

function setTheme({
  color, name,
}: Theme) {
  // const { app } = useNotCool()

  const { get, set } = useLocalStorage('theme')
  // 主题配置
  const theme = get() || {}

  // 变量前缀
  const pre = '--el-color-primary'

  // 白色混合色
  const mixWhite = '#ffffff'

  // 黑色混合色
  const mixBlack = '#000000'

  // 元素
  const el = document.documentElement

  // 主题
  if (name) {
    const item = themes.find((e) => e.name == name)

    if (item) {
      if (!color) {
        color = item.color
      }
    }
    document.body?.setAttribute('class', `theme-${name}`)

    theme.name = name
  }

  // 设置主色
  if (color) {
    el.style.setProperty(pre, color)
    el.style.setProperty('--color-primary', color)

    // 设置辅色
    for (let i = 1; i < 10; i += 1) {
      el.style.setProperty(`${pre}-light-${i}`, mix(color, mixWhite, i * 0.1))
      el.style.setProperty(`${pre}-dark-${i}`, mix(color, mixBlack, i * 0.1))
    }

    theme.color = color
  }

  set(theme)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

这里有一个存入缓存和取缓存的操作,是为了刷新后不丢失之前选择的样式。

# 拓展

可以参考element的做法通过css变量确定自己网站的整体颜色基调,这样后续切换主题会非常方便。其实还可以通过给所有类名加不同的父类名来进行主题切换,但是这种方案要预设主题,不灵活。而且要写很多样式,也非常的不方便。所以综合下来还是css变量最好用!

编辑 (opens new window)
上次更新: 2023/09/06, 09:59:30
h5下载vcard快捷保存联系人信息
解决monorepo场景下子包作为依赖项在开发和生产暴露文件的问题

← h5下载vcard快捷保存联系人信息 解决monorepo场景下子包作为依赖项在开发和生产暴露文件的问题→

最近更新
01
前端检测更新,自动刷新网页
06-09
02
swiper渲染大量数据的优化方案
06-06
03
仿抖音短视频组件实现方案
02-28
更多文章>
Theme by Vdoing | Copyright © 2023-2025 UzumakiItachi | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式