vue3+elementPlus 如何定制化主题

前言

最近在学习vue3及其周围的生态,然后想做一个自定义主题的后台管理系统。

自定义主题原理

俗话说工欲善其事必先利其器,做这个之前我们得先了解其背后的原理。

CSS 自定义主题的原理是基于 CSS 变量的动态性和可重用性。通过修改这些变量的值,可以轻松地在整个网站或应用中实现主题切换或样式调整,而无需直接修改多处 CSS 代码。

自定义主题的实现步骤大致如下:

  1. 定义 CSS 变量: 在 CSS 中,可以在 :root 选择器或其他作用域内定义变量。例如,可以定义一组代表颜色、字体大小、边距等的变量。

    css 复制代码
    :root {
        --color-primary: #007bff;
        --color-secondary: #6c757d;
        --font-size-base: 16px;
        --spacing-base: 1rem;
    }
  2. 使用 CSS 变量: 在样式表的其他部分,使用 var(--variable-name) 函数引用这些变量。这样,所有使用这些变量的样式都会自动应用变量的值。

    css 复制代码
    body {
        font-size: var(--font-size-base);
        background-color: var(--color-primary);
    }
  3. 动态修改变量值: 通过 JavaScript,可以在运行时动态修改 CSS 变量的值。这常通过修改 :root 或其他元素的样式属性来实现。

    javascript 复制代码
    document.documentElement.style.setProperty('--color-primary', '#ff4500');
  4. 实现自定义主题: 通过为不同主题预定义一组变量值,并在选择主题时动态应用这些值。

技术栈

介绍完原理介绍一下我实现用到的技术栈

  • vue3
  • vue-router
  • pinia
  • element-plus
  • unocss
  • sass
  • vueuse
    • 它提供了一套可重用的 Composition API 函数。这些函数覆盖了各种常见的 Web 应用需求,比如状态管理、DOM 操作、事件监听、生命周期管理等(总之大佬牛)。

实现历程

目前element-puls已经提供了暗黑模式只需要引入暗黑模式的样式并且改变html的class即可切换。

html 复制代码
<html class="dark">
  <head></head>
  <body></body>
</html>
js 复制代码
import 'element-plus/theme-chalk/dark/css-vars.css'

如何去覆盖暗黑模式的css变量呢? 创建css-vars.css文件

css 复制代码
html.dark {
  /* 自定义深色背景颜色 */
  --el-bg-color: #626aef;
}

按照官网的思路实现了自定义暗黑主题

scss 复制代码
@use 'sass:map';
@use 'sass:math';

html.dark {
  $colors:(
  'white': #ffffff,
  'black': #000000,
  'primary': (
    'base': pink,
  ),
  'success': (
    'base': #67c23a,
  ),
  'warning': (
    'base': #e6a23c,
  ),
  'danger': (
    'base': #f56c6c,
  ),
  'error': (
    'base': #f56c6c,
  ),
  'info': (
    'base': #909399,
  ),
);
  @mixin set-color-type($type,$color,$value){
      --el-#{$type}-#{$color}:#{$value};
  }
  $types: primary, success, warning, danger, error, info;
  @each $type in $types{
    @include set-color-type('color',$type,map.get($colors,$type,'base'))
  }
};
  • 这里是在html.dark类名下生成了几个主体色的颜色--el-color-primary、--el-color-success等。

当然这里只是对element的color进行了重写,还有bg text等需要的可以自己重写。

并且使用vueuse中的useDark去对html的class进行切换

xml 复制代码
<template>
  <el-button @click="toggleDark()">切换</el-button>
</template>

<script setup lang="ts">
const isDark = useDark({
  selector: "html",
  attribute: 'class',
  valueDark: 'dark',
  valueLight: 'light',
})
const toggleDark = useToggle(isDark)
</script>

<style></style>
  • selector:选择器
  • attribute:修改的属性
  • valueDark:暗黑模式下的值
  • valueLight:非暗黑模式下的值

效果图

到此为止已经实现了暗黑和光亮的两个主体,离我们自定义主题还有点距离。

vueuse的useCssVar 去改变css的变量

js 复制代码
<template>
  <i class="i-carbon:aperture text-[30px] mt-3" @click="showDrawer" />
  <el-drawer v-model="drawer" title="I am the title" :direction="direction" :before-close="handleClose">
    <div class="demo-color-block">
      <span class="demonstration">primary</span>
      <el-color-picker v-model="color" @active-change="changeColor" />
    </div>
  </el-drawer>
</template>

<script setup lang="ts">
const drawer = ref(false)
const color = ref()
const setPrimaryColor = useCssVar("--el-color-primary", document.documentElement)
const showDrawer = () => {
  drawer.value = true
}
const changeColor = (c) => {
  setPrimaryColor.value = c
}
</script>

<style></style>
  • useCssVar:设置改变的变量名和作用在什么位置上
  • changeColor:修改变量名

效果图

相关推荐
Deng9452013143 分钟前
Vue + Flask 前后端分离项目实战:从零搭建一个完整博客系统
前端·vue.js·flask
威迪斯特5 分钟前
Flask:轻量级Web框架的技术本质与工程实践
前端·数据库·后端·python·flask·开发框架·核心架构
Hello.Reader30 分钟前
Flink 文件系统通用配置默认文件系统与连接数限制实战
vue.js·flink·npm
wuhen_n32 分钟前
JavaScript内置数据结构
开发语言·前端·javascript·数据结构
大鱼前端33 分钟前
为什么我说CSS-in-JS是前端“最佳”的糟粕设计?
前端
不爱吃糖的程序媛36 分钟前
Capacitor:跨平台Web原生应用开发利器,现已全面适配鸿蒙
前端·华为·harmonyos
AC赳赳老秦38 分钟前
2026国产算力新周期:DeepSeek实战适配英伟达H200,引领大模型训练效率跃升
大数据·前端·人工智能·算法·tidb·memcache·deepseek
CHU72903539 分钟前
淘宝扭蛋机抽盒小程序前端功能解析:解锁趣味抽盒新体验
前端·小程序
-凌凌漆-1 小时前
【npm】npm的-D选项介绍
前端·npm·node.js
鹿心肺语1 小时前
前端HTML转PDF的两种主流方案深度解析
前端·javascript