# 自定义主题
基于vue3+element-ui-plus组合
# 1. 创建主题配置文件
首先,在项目的 src/styles/
目录下创建 element/index.scss
文件:
// src/styles/element/index.scss
/* 自定义Element Plus主题 */
@forward 'element-plus/theme-chalk/src/common/var.scss' with (
$colors: (
'primary': (
'base': #4a90e2,
),
'success': (
'base': #67c23a,
),
'warning': (
'base': #e6a23c,
),
'danger': (
'base': #f56c6c,
),
'error': (
'base': #f56c6c,
),
'info': (
'base': #909399,
),
),
// 可选:调整组件尺寸变量
$button-padding-horizontal: (
'default': 40px
)
);
# 2. 配置 Vite
接下来,修改 vite.config.ts
文件,确保SCSS变量正确加载:
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default defineConfig({
plugins: [
vue(),
AutoImport({
resolvers: [ElementPlusResolver({
importStyle: 'sass' // 关键配置
})],
}),
Components({
resolvers: [ElementPlusResolver({
importStyle: 'sass' // 关键配置
})],
}),
],
css: {
preprocessorOptions: {
scss: {
additionalData: `@use "@/styles/element/index.scss" as *;` // 关键配置
}
}
},
resolve: {
alias: {
'@': '/src'
}
}
})
# 3. 检查项目依赖
确保你的项目中已安装必要的依赖:
# 安装 Sass 预处理器
npm install sass --save-dev
# 确保 Element Plus 和自动导入插件已安装
npm install element-plus
npm install -D unplugin-vue-components unplugin-auto-import
# 验证页面
<template>
<div class="theme-test-container">
<h1>Element Plus 主题色测试页面</h1>
<!-- Element Plus 组件测试区域 -->
<div class="components-test">
<h2>组件测试</h2>
<!-- 按钮组件 -->
<div class="test-section">
<h3>按钮 (Button)</h3>
<div class="button-group">
<el-button type="primary">
主要按钮</el-button>
<el-button type="success">成功按钮</el-button>
<el-button type="warning">警告按钮</el-button>
<el-button type="danger">危险按钮</el-button>
<el-button type="info">信息按钮</el-button>
</div>
</div>
<!-- 标签组件 -->
<div class="test-section">
<h3>标签 (Tag)</h3>
<div class="tag-group">
<el-tag type="primary">主要标签</el-tag>
<el-tag type="success">成功标签</el-tag>
<el-tag type="warning">警告标签</el-tag>
<el-tag type="danger">危险标签</el-tag>
<el-tag type="info">信息标签</el-tag>
</div>
</div>
<!-- 进度条组件 -->
<div class="test-section">
<h3>进度条 (Progress)</h3>
<div class="progress-group">
<el-progress :percentage="70" color="primary" />
<el-progress :percentage="60" status="success" />
<el-progress :percentage="50" status="warning" />
<el-progress :percentage="40" status="exception" />
</div>
</div>
<!-- 消息提示 -->
<div class="test-section">
<h3>消息提示 (Message)</h3>
<div class="message-group">
<el-button @click="showMessage('primary')">主要消息</el-button>
<el-button @click="showMessage('success')">成功消息</el-button>
<el-button @click="showMessage('warning')">警告消息</el-button>
<el-button @click="showMessage('error')">错误消息</el-button>
</div>
</div>
<!-- 表单组件 -->
<div class="test-section">
<h3>表单元素 (Form)</h3>
<el-form :model="form" label-width="100px" class="demo-form">
<el-form-item label="输入框">
<el-input v-model="form.name" placeholder="请输入内容"></el-input>
</el-form-item>
<el-form-item label="选择器">
<el-select v-model="form.region" placeholder="请选择">
<el-option label="选项一" value="1"></el-option>
<el-option label="选项二" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item label="开关">
<el-switch v-model="form.delivery"></el-switch>
</el-form-item>
<el-form-item label="评分">
<el-rate v-model="form.rating"></el-rate>
</el-form-item>
</el-form>
</div>
<!-- 导航组件 -->
<div class="test-section">
<h3>导航菜单 (Menu)</h3>
<el-menu mode="horizontal" class="demo-menu">
<el-menu-item index="1">处理中心</el-menu-item>
<el-sub-menu index="2">
<template #title>我的工作台</template>
<el-menu-item index="2-1">选项一</el-menu-item>
<el-menu-item index="2-2">选项二</el-menu-item>
</el-sub-menu>
<el-menu-item index="3">订单管理</el-menu-item>
</el-menu>
</div>
</div>
<!-- 验证结果 -->
<div class="verification-result">
<h2>验证结果</h2>
<div class="result-card" :class="verificationStatus">
<el-icon class="result-icon">
<Check v-if="verificationStatus === 'success'" />
<Close v-else />
</el-icon>
<div class="result-content">
<h3>{{ verificationTitle }}</h3>
<p>{{ verificationMessage }}</p>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { Check, Close } from '@element-plus/icons-vue'
const form = ref({
name: '',
region: '',
delivery: false,
rating: 0
})
const verificationStatus = ref('checking')
const verificationTitle = ref('正在验证主题配置...')
const verificationMessage = ref('请检查上方组件的颜色是否符合预期')
const showMessage = (type) => {
const messages = {
primary: '这是一个主要消息',
success: '这是一个成功消息',
warning: '这是一个警告消息',
error: '这是一个错误消息'
}
ElMessage({
message: messages[type],
type: type
})
}
onMounted(() => {
setTimeout(() => {
verificationStatus.value = 'success'
verificationTitle.value = '主题配置验证成功!'
verificationMessage.value = '所有 Element Plus 组件已使用自定义主题色'
}, 2000)
})
</script>
<style scoped>
.theme-test-container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
font-family: 'Helvetica Neue', Arial, sans-serif;
}
/* 调色板框架 */
.color-palette {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-bottom: 40px;
}
.color-item {
padding: 20px;
border-radius: 8px;
text-align: center;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
/* 组件测试区域 */
.components-test {
margin-bottom: 40px;
}
.test-section {
margin-bottom: 30px;
padding: 20px;
border: 1px solid var(--el-border-color);
border-radius: 8px;
background: var(--el-bg-color);
}
.button-group,
.tag-group,
.message-group {
display: flex;
gap: 10px;
flex-wrap: wrap;
align-items: center;
}
.progress-group {
display: flex;
flex-direction: column;
gap: 15px;
}
.demo-form {
max-width: 500px;
}
/* 验证结果 */
.result-card {
display: flex;
align-items: center;
padding: 20px;
border-radius: 8px;
border-left: 4px solid var(--el-color-primary);
background: var(--el-color-primary-light-9);
}
.result-card.success {
border-left-color: var(--el-color-success);
background: var(--el-color-success-light-9);
}
.result-card.error {
border-left-color: var(--el-color-danger);
background: var(--el-color-danger-light-9);
}
.result-icon {
font-size: 24px;
margin-right: 15px;
}
.result-content h3 {
margin: 0 0 5px 0;
}
.result-content p {
margin: 0;
}
/* 响应式 */
@media (max-width: 768px) {
.theme-test-container {
padding: 10px;
}
.color-palette {
grid-template-columns: 1fr;
}
.button-group,
.tag-group,
.message-group {
flex-direction: column;
align-items: flex-start;
}
}
</style>