Vue 3+Vite+TypeScript项目中使用Element Plus实现主题切换(明亮主题、暗黑主题、蓝色主题)

一、

首先,在CSS中定义两种主题(亮色和暗色)的样式,并使用CSS变量来控制颜色。

css 复制代码
/* base.css */  
:root {  
    --bg-color: #ffffff; /* 背景颜色,默认为白色 */  
    --text-color: #000000; /* 文本颜色,默认为黑色 */  
    --link-color: #0000ee; /* 链接颜色 */  
    --button-bg-color: #f0f0f0; /* 按钮背景颜色 */  
    --button-text-color: #000000; /* 按钮文本颜色 */  
}  
  
body {  
    background-color: var(--bg-color);  
    color: var(--text-color);  
    transition: background-color 0.3s, color 0.3s;  
}  
  
a {  
    color: var(--link-color);  
}  
  
button {  
    background-color: var(--button-bg-color);  
    color: var(--button-text-color);  
    border: none;  
    padding: 10px 20px;  
    cursor: pointer;  
    transition: background-color 0.3s, color 0.3s;  
}  
  
/* 暗黑模式样式 */  
body.dark-mode {  
    --bg-color: #333333;  
    --text-color: #ffffff;  
    --link-color: #00eeff;  
    --button-bg-color: #444444;  
    --button-text-color: #ffffff;  
}

二、

确保你已经安装了Element Plus和相关依赖

css 复制代码
npm install element-plus
npm install @vueuse/core

在你的`main.ts`文件中引入Element Plus和相关样式

javascript 复制代码
import { createApp } from 'vue';
import App from './App.vue';
import ElementPlus from 'element-plus';
import 'element-plus/theme-chalk/dark/css-vars.css';
import './styles/index.css'; // 用于自定义主题的样式

const app = createApp(App);

app.use(ElementPlus);

app.mount('#app');

在`src`目录下创建一个`theme.ts`文件,用于管理主题切换的逻辑

javascript 复制代码
import { ref } from 'vue';
import { usePreferredDark } from '@vueuse/core';

const isDark = ref(usePreferredDark());

export function useTheme() {
  const toggleTheme = (theme: 'light' | 'dark' | 'blue') => {
    const classList = document.documentElement.classList;
    if (theme === 'light') {
      classList.remove('dark');
      classList.remove('blue');
    } else if (theme === 'dark') {
      classList.add('dark');
      classList.remove('blue');
    } else if (theme === 'blue') {
      classList.add('blue');
      classList.remove('dark');
    }
  };

  return { isDark, toggleTheme };
}

在`src/styles`目录下创建一个`index.css`文件,并定义你的主题样式

css 复制代码
/* index.css */

/* 全局基础样式 */
html {
  --el-color-primary: #409eff; /* 默认主题色 */
  --el-color-success: #67c23a;
  --el-color-warning: #e6a23c;
  --el-color-danger: #f56c6c;
  --el-color-info: #909399;

  --el-border-radius-base: 4px;
  --el-border-color-base: #dcdfe6;
}

/* 暗黑主题样式 */
html.dark {
  --el-color-primary: #1f1f1f; /* 暗黑主题色 */
  --el-color-success: #67c23a;
  --el-color-warning: #e6a23c;
  --el-color-danger: #f56c6c;
  --el-color-info: #909399;

  --el-border-radius-base: 4px;
  --el-border-color-base: #303133;

  --el-bg-color: #1f1f1f; /* 背景色 */
  --el-text-color-primary: #ffffff; /* 主要文本色 */
  --el-text-color-regular: #dcdfe6; /* 常规文本色 */
  --el-text-color-placeholder: #909399; /* 占位符色 */
}

/* 蓝色主题样式 */
html.blue {
  --el-color-primary: #1e90ff; /* 蓝色主题色 */
  --el-color-success: #67c23a;
  --el-color-warning: #e6a23c;
  --el-color-danger: #f56c6c;
  --el-color-info: #909399;

  --el-border-radius-base: 4px;
  --el-border-color-base: #dcdfe6;
}

/* 覆盖Element Plus组件样式 */
.el-button {
  border-radius: var(--el-border-radius-base);
  background-color: var(--el-color-primary);
  color: #fff;
}

.el-button--primary {
  background-color: var(--el-color-primary);
  border-color: var(--el-color-primary);
}

.el-button--success {
  background-color: var(--el-color-success);
  border-color: var(--el-color-success);
}

.el-button--warning {
  background-color: var(--el-color-warning);
  border-color: var(--el-color-warning);
}

.el-button--danger {
  background-color: var(--el-color-danger);
  border-color: var(--el-color-danger);
}

.el-button--info {
  background-color: var(--el-color-info);
  border-color: var(--el-color-info);
}

.el-input__inner {
  border-color: var(--el-border-color-base);
  background-color: var(--el-bg-color);
  color: var(--el-text-color-primary);
}

.el-input__placeholder {
  color: var(--el-text-color-placeholder);
}

.el-table th,
.el-table td {
  border-color: var(--el-border-color-base);
  color: var(--el-text-color-primary);
  background-color: var(--el-bg-color);
}

.el-menu {
  background-color: var(--el-bg-color);
  color: var(--el-text-color-regular);
}

.el-menu-item.is-active {
  background-color: var(--el-color-primary);
  color: #fff;
}

/* 根据主题调整其他组件样式 */
.el-header,
.el-footer {
  background-color: var(--el-bg-color);
  color: var(--el-text-color-primary);
}

.el-main {
  background-color: var(--el-bg-color);
}

.el-pagination__total,
.el-pagination__sizes,
.el-pagination__prev,
.el-pagination__pager,
.el-pagination__next,
.el-pagination__jump {
  color: var(--el-text-color-primary);
}

创建一个`ThemeSwitcher.vue`组件,用于切换主题

html 复制代码
<template>
  <div>
    <el-select v-model="selectedTheme" placeholder="Select Theme" @change="onThemeChange">
      <el-option label="Light" value="light"></el-option>
      <el-option label="Dark" value="dark"></el-option>
      <el-option label="Blue" value="blue"></el-option>
    </el-select>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue';
import { useTheme } from '@/theme';

export default defineComponent({
  setup() {
    const { toggleTheme } = useTheme();
    const selectedTheme = ref<'light' | 'dark' | 'blue'>('light');

    const onThemeChange = (theme: 'light' | 'dark' | 'blue') => {
      toggleTheme(theme);
    };

    return {
      selectedTheme,
      onThemeChange,
    };
  },
});
</script>

<style scoped>
/* 可添加本地样式 */
</style>

在App.vue中使用主题切换组件

html 复制代码
<template>
  <div id="app">
    <theme-switcher />
    <router-view />
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import ThemeSwitcher from './components/ThemeSwitcher.vue';

export default defineComponent({
  components: {
    ThemeSwitcher,
  },
});
</script>

确保在`vite.config.ts`中包含以下配置,以支持CSS变量和预处理:

javascript 复制代码
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [vue()],
  css: {
    preprocessorOptions: {
      scss: {
        additionalData: `@import "./src/styles/variables.scss";`
      }
    }
  }
});
相关推荐
会发光的猪。10 分钟前
【 ElementUI 组件Steps 步骤条使用新手详细教程】
前端·javascript·vue.js·elementui·前端框架
我家媳妇儿萌哒哒10 分钟前
el-table合并单元格之后,再进行隔行换色的且覆盖表格行鼠标移入的背景色的实现
前端·javascript·elementui
baiduguoyun26 分钟前
react的import 导入语句中的特殊符号
前端·react.js
前端青山27 分钟前
webpack指南
开发语言·前端·javascript·webpack·前端框架
NiNg_1_23439 分钟前
ECharts实现数据可视化入门详解
前端·信息可视化·echarts
程序媛小果1 小时前
基于java+SpringBoot+Vue的桂林旅游景点导游平台设计与实现
java·vue.js·spring boot
励志前端小黑哥1 小时前
有了Miniconda,再也不用担心nodejs、python、go的版本问题了
前端·python
喵叔哟1 小时前
重构代码之取消临时字段
java·前端·重构
还是大剑师兰特2 小时前
D3的竞品有哪些,D3的优势,D3和echarts的对比
前端·javascript·echarts
王解2 小时前
【深度解析】CSS工程化全攻略(1)
前端·css