elementui Plus 主题色修改(自定义换肤等)

效果:实现自定义选颜色,修改整体配色 ,达到换肤 换主题色等效果

  • 点击颜色选择器,选中,然后所有的主题色都会变化,并且整体配色都会变,比如hover,背景等,主要体现在按钮和主题颜色

image

2,选了紫色
image

3.鼠标放上去的颜色。颜色变淡等
image

image

代码实现
main.vue 展示页

<template>
  <div class="Main">
    我是主页面
    <el-button type="primary">主题色</el-button>
    <el-button type="default">默认色</el-button>
    <el-button type="warning">警告色</el-button>
    <el-button type="success">成功色</el-button>
    <el-button type="info">信息色</el-button>
    <el-button type="danger">危险色</el-button>
  </div>
</template>

<script setup>
// 导入需要的 API(按需添加)

// 组件逻辑写在这里
console.log('Main 组件加载');
</script>

<style scoped lang="scss">
.Main {
  // 样式写在这里
}
</style>

APP.vue 定义全局颜色
注意点:
给color一个默认值,默认值存在pinia中

  • computed(() => ...):创建一个“派生值”,它会依赖函数里的响应式源并自动更新;如果写了 set,还能双向绑定。
  • themeStore.currentTheme 是一个响应式源
  • const color = ref(themeStore.currentTheme) 只是把当前值“拿出来”一次,color 之后不会随着 themeStore.currentTheme 变化而自动更新
  • 而 computed({ get: () => themeStore.currentTheme, set: (v) => themeStore.setTheme(v) }) 则是直接绑定到 store,读的时候总是拿最新值,改的时候也能同步回 store
<script setup>
import { useThemeStore } from './stores/theme'
import { computed, ref } from 'vue'
const themeStore = useThemeStore()
const color = computed({
  get: () => themeStore.currentTheme,
  set: (value) => themeStore.setTheme(value),
})
const predefineColors = ref([
  '#ff4500',
  '#ff8c00',
  '#ffd700',
  '#90ee90',
  '#00ced1',
  '#1e90ff',
  '#c71585',
  'rgba(255, 69, 0, 0.68)',
  'rgb(255, 120, 0)',
  'hsv(51, 100, 98)',
  'hsva(120, 40, 94, 0.5)',
  'hsl(181, 100%, 37%)',
  'hsla(209, 100%, 56%, 0.73)',
  '#c7158577',
])

</script>

<template>
  <div class="toggleColor">
    <el-color-picker v-model="color" show-alpha :predefine="predefineColors" />
  </div>
  <RouterView />
</template>

<style scoped>
body{
  position: relative;
}
.toggleColor{
  position: fixed;
  bottom: 20px;
  right: 20px;
  z-index: 9999;
}


</style>

theme.js 状态管理页
color-mix(in srgb, ${theme} 70%, white 30%)

  • 原生 CSS 函数,浏览器自带,不用装任何库
  • 不用解析 rgb /hex/rgba,直接传字符串就行
import { ref } from 'vue'
import { defineStore } from 'pinia'

export const useThemeStore = defineStore('theme', () => {
  const currentTheme = ref('#D3602B') // 默认主题颜色

  function setTheme(theme) {
    currentTheme.value = theme
    const el = document.documentElement
    el.style.setProperty('--el-color-primary', theme)
    el.style.setProperty('--themered-color', theme)
    // CSS color-mix,兼容更多格式的颜色输入
    el.style.setProperty(
      '--el-color-primary-light-3',
      `color-mix(in srgb, ${theme} 70%, white 30%)`,
    )
    el.style.setProperty(
      '--el-color-primary-light-5',
      `color-mix(in srgb, ${theme} 50%, white 50%)`,
    )
    el.style.setProperty(
      '--el-color-primary-light-7',
      `color-mix(in srgb, ${theme} 30%, white 70%)`,
    )
    el.style.setProperty(
      '--el-color-primary-light-9',
      `color-mix(in srgb, ${theme} 10%, white 90%)`,
    )
    el.style.setProperty('--el-color-primary-dark-2', `color-mix(in srgb, ${theme} 80%, black 20%)`)
    localStorage.setItem('theme', theme)
  }

  function loadTheme() {
    const saved = localStorage.getItem('theme')
    if (saved) {
      setTheme(saved)
    }
  }

  return { currentTheme, setTheme, loadTheme }
})

main.js 全局入口文件
注意useThemeStore(pinia) 要加入pinia

  • app.use(pinia) 注册了 Pinia 插件
  • 但 useThemeStore() 在挂载前执行时,不能自动从 Vue 应用上下文里获取 Pinia
  • 所以要显式传入 pinia 实例:useThemeStore(pinia)
    这样才能保证 themeStore.loadTheme() 使用的是同一个 Pinia 实例,而不是“无上下文 / 默认容器”。
import './assets/main.css'

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import './styles/variable.scss' // 引入自定义的 SCSS 变量文件

import App from './App.vue'
import router from './router'
import { useThemeStore } from './stores/theme'

const app = createApp(App)
const pinia = createPinia()
app.use(ElementPlus)
app.use(pinia)
app.use(router)

const themeStore = useThemeStore(pinia)
themeStore.loadTheme()

app.mount('#app')
posted @ 2026-03-30 21:16  张尊娟  阅读(14)  评论(0)    收藏  举报