Appearance
BizThemeSwitch 主题切换
明暗主题一键切换图标按钮:切换 document.documentElement 的 dark class(Element Plus 暗色变量约定,组件库全部 --el-* 变量自动适配),localStorage 持久化 + 系统偏好跟随(prefers-color-scheme),支持 v-model 受控。
基础用法
当前主题:亮色
v-model 双向同步当前主题;默认持久化(刷新保持),首次访问跟随系统。
<script setup lang="ts">
/** 基础用法:一键明暗切换(整站 html.dark 生效,刷新保持) */
import { ref } from 'vue'
import { BizThemeSwitch } from 'vue3-ep-biz-lib'
const theme = ref<'light' | 'dark'>('light')
</script>
<template>
<div class="bar">
<span class="label">当前主题:{{ theme === 'dark' ? '暗色' : '亮色' }}</span>
<BizThemeSwitch v-model="theme" />
</div>
</template>
<style scoped>
.bar {
display: flex;
align-items: center;
gap: 12px;
}
.label {
font-size: 14px;
}
</style>
显示代码
受控 · 偏好上报
storage-key="" 关闭持久化;change 事件联动后端保存用户偏好。<script setup lang="ts">
/** 进阶:受控模式 + change 事件(联动后端保存用户偏好) */
import { ElMessage } from 'element-plus'
import { BizThemeSwitch } from 'vue3-ep-biz-lib'
const onChange = (value: 'light' | 'dark'): void => {
ElMessage.info(`主题切换为 ${value === 'dark' ? '暗色' : '亮色'}(change 事件可上报后端保存偏好)`)
}
</script>
<template>
<BizThemeSwitch storage-key="" default-theme="light" @change="onChange" />
</template>
显示代码
双入口同步
顶栏(当前 light)
设置页两处共享同一 v-model,状态一致
顶栏与设置页共享 v-model(storage-key 置空避免双写竞争)。
<script setup lang="ts">
/** 双入口同步:顶栏与设置页共享 v-model(切换任意一处两处同步) */
import { ref } from 'vue'
import { BizThemeSwitch } from 'vue3-ep-biz-lib'
const theme = ref<'light' | 'dark'>('light')
</script>
<template>
<div class="box">
<div class="bar">
<span class="label">顶栏</span>
<BizThemeSwitch v-model="theme" storage-key="" />
<span class="tip">(当前 {{ theme }})</span>
</div>
<div class="bar">
<span class="label">设置页</span>
<BizThemeSwitch v-model="theme" storage-key="" default-theme="light" />
<span class="tip">两处共享同一 v-model,状态一致</span>
</div>
</div>
</template>
<style scoped>
.box {
display: flex;
flex-direction: column;
gap: 10px;
}
.bar {
display: flex;
align-items: center;
gap: 10px;
}
.label {
width: 56px;
font-size: 13px;
color: var(--el-text-color-secondary);
}
.tip {
font-size: 12px;
color: var(--el-text-color-secondary);
}
</style>
显示代码
持久化验证
选择后刷新本页:主题保持(localStorage: demo-theme-persist);清除存储则回退 auto 跟随系统
独立 storage-key;刷新保持,清除存储回退 auto 跟随系统。
<script setup lang="ts">
/** 持久化验证:刷新页面保持选择(default-theme 兜底) */
import { BizThemeSwitch } from 'vue3-ep-biz-lib'
</script>
<template>
<div class="box">
<BizThemeSwitch storage-key="demo-theme-persist" default-theme="auto" />
<span class="tip">选择后刷新本页:主题保持(localStorage: demo-theme-persist);清除存储则回退 auto 跟随系统</span>
</div>
</template>
<style scoped>
.box {
display: flex;
align-items: center;
gap: 10px;
}
.tip {
font-size: 13px;
color: var(--el-text-color-secondary);
max-width: 360px;
}
</style>
显示代码
顶栏三件套
运营平台
3
管通知 + BizFullScreen + 主题切换 + 头像的 header-right 组合位。
<script setup lang="ts">
/** 顶栏组合位:通知 + 全屏 + 主题切换(常见 header-right 三件套) */
import { ref } from 'vue'
import { Bell } from '@element-plus/icons-vue'
import { BizFullScreen, BizThemeSwitch } from 'vue3-ep-biz-lib'
const count = ref(3)
</script>
<template>
<div class="header">
<span class="title">运营平台</span>
<div class="right">
<ElBadge :value="count">
<ElIcon :size="18" style="cursor: pointer" @click="count = 0"><Bell /></ElIcon>
</ElBadge>
<BizFullScreen />
<BizThemeSwitch storage-key="" />
<ElAvatar :size="28">管</ElAvatar>
</div>
</div>
</template>
<style scoped>
.header {
display: flex;
align-items: center;
justify-content: space-between;
height: 48px;
padding: 0 16px;
border: 1px solid var(--el-border-color-light);
border-radius: var(--el-border-radius-base);
}
.title {
font-weight: 600;
}
.right {
display: flex;
align-items: center;
gap: 16px;
}
</style>
显示代码
外观设置卡
外观
暗色适合夜间值守;选择会保存到本机并由后端偏好下发
设置页形态:change 事件上报后端偏好(下次登录下发注入)。
<script setup lang="ts">
/** 外观设置卡:主题 + 说明行(设置页常见形态,storage-key 独立) */
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { BizThemeSwitch } from 'vue3-ep-biz-lib'
const theme = ref<'light' | 'dark'>('light')
const onChange = (value: 'light' | 'dark'): void => {
ElMessage.info(`偏好已上报后端:${value}(刷新后从用户配置拉取再注入)`)
}
</script>
<template>
<div class="card">
<div class="row">
<div>
<div class="name">外观</div>
<div class="desc">暗色适合夜间值守;选择会保存到本机并由后端偏好下发</div>
</div>
<BizThemeSwitch v-model="theme" storage-key="demo-theme-card" @change="onChange" />
</div>
</div>
</template>
<style scoped>
.card {
max-width: 420px;
padding: 16px;
border: 1px solid var(--el-border-color-light);
border-radius: var(--el-border-radius-base);
}
.row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
}
.name {
font-size: 14px;
font-weight: 600;
}
.desc {
margin-top: 4px;
font-size: 12px;
color: var(--el-text-color-secondary);
max-width: 280px;
}
</style>
显示代码
Props
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| v-model | 'light' | 'dark' | — | 受控当前主题(不传则由持久化值 / defaultTheme 决定) |
| storage-key | string | 'biz-theme' | localStorage key(空串不持久化) |
| default-theme | 'light' | 'dark' | 'auto' | 'auto' | 初始主题(auto 跟随系统) |
Events
| 事件名 | 参数 | 说明 |
|---|---|---|
| update:model-value | (value) | 主题变化 |
| change | (value) | 主题变化(上报后端场景用) |
Slots
| 插槽名 | 说明 |
|---|---|
| — | 无插槽 |
Expose
| 属性/方法 | 说明 |
|---|---|
| — | 无 |