一、
首先,在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";`
}
}
}
});