主要代码文件
head-seeting.vue
<script setup lang="ts">
import { ref } from 'vue'
import { useGlobalStore } from '@/stores/global'
import ColorPicker from '@/components/base-color-picker/index.vue'
const open = ref(false)
/**
* 打开layout布局抽屉
*/
const showLayoutDrawer = () => {
open.value = true
}
// 整体风格设置
const sideStyleList = [
{
tips: '亮色主题风格',
value: 'light',
url: 'https://gw.alipayobjects.com/zos/antfincdn/NQ%24zoisaD2/jpRkZQMyYRryryPNtyIC.svg',
},
{
tips: '暗色主题风格',
value: 'dark',
url: 'https://gw.alipayobjects.com/zos/antfincdn/XwFOFbLkSM/LCkqqYNmvBEbokSDscrm.svg',
},
]
/**
* 子组件传递的颜色
* @param color 颜色
*/
function updateColor(color: any) {
useGlobalStore().setTagColor(color)
}
</script>
<template>
<div class="layout">
<LayoutOutlined @click="showLayoutDrawer" />
</div>
<a-drawer
v-model:open="open"
placement="right"
:closable="false"
size="default"
>
<div>
<h3>整体风格设置</h3>
<div class="layout-icon">
<a-tooltip v-for="(item, index) in sideStyleList" :key="index">
<template #title>
<span>{{ item.tips }}</span>
</template>
<img
:src="item.url"
:alt="item.tips"
@click="useGlobalStore().setSideStyle(item.value)"
/>
<div class="checkbox">
<check-outlined
v-if="useGlobalStore().theme === item.value"
class="checkbox-select"
/>
</div>
</a-tooltip>
</div>
<a-divider />
<div class="theme-color">
<h3>主题色</h3>
<div class="theme-color-content">
主题颜色:
<color-picker
:open="open"
:color="useGlobalStore().themeColor"
@update:color="updateColor"
></color-picker>
</div>
</div>
<a-divider />
<a-form class="text-right">
<a-form-item label="灰色模式">
<a-switch
:checked="useGlobalStore().isGrey"
@change="useGlobalStore().setGrey(!useGlobalStore().isGrey)"
/>
</a-form-item>
<a-form-item label="模块坞图标">
<a-switch
:checked="useGlobalStore().moduleUnfoldIconOpen"
@change="useGlobalStore().setModuleUnfoldIcon()"
/>
</a-form-item>
<a-form-item label="显示LOGO">
<a-switch
:checked="useGlobalStore().logoOpen"
@change="useGlobalStore().setLogo()"
/>
</a-form-item>
<a-form-item label="折叠菜单">
<a-switch
:checked="useGlobalStore().collapsed"
@change="useGlobalStore().setMenusState()"
/>
</a-form-item>
</a-form>
<a-alert
message="以上配置可实时预览,不建议在生产环境下开放布局设置"
type="warning"
/>
</div>
</a-drawer>
</template>
<style lang="less" scoped>
@import '@/style/theme.css';
.layout {
min-width: 40px;
padding: 8px;
color: #666;
font-size: 18px;
text-align: center;
cursor: pointer;
&:hover {
background-color: #e2e2e2;
border-radius: 5px;
}
}
.layout-icon {
display: flex;
margin-bottom: 20px;
cursor: pointer;
img {
z-index: 999;
width: 50px;
height: 42px;
margin-right: 16px;
overflow: hidden;
border-radius: 2px;
}
.checkbox {
position: relative;
.checkbox-select {
position: absolute;
right: 27px;
bottom: 12px;
color: var(--themeColor);
font-weight: 700;
font-size: 14px;
pointer-events: none;
}
}
}
.theme-color {
.theme-color-content {
display: flex;
margin-top: 20px;
line-height: 30px;
}
}
.text-right {
text-align: right;
}
</style>
global.ts
import { defineStore } from 'pinia'
/**
* 主题
*/
export const useGlobalStore = defineStore({
id: 'global',
/**
* state
*/
state: () => ({
/**
* 整体风格设置
*/
theme: localStorage.getItem('theme') || 'light',
/**
* 主题色
*/
themeColor: localStorage.getItem('themeColor') || '#1890FF',
/**
* 灰色模式
*/
isGrey: false,
/**
* 模块坞图标
*/
moduleUnfoldIconOpen: false,
/**
* 显示LOGO
*/
logoOpen: true,
/**
* 菜单是否折叠
*/
collapsed: false,
}),
actions: {
/**
* 设置整体风格主题
* @param value value
*/
setSideStyle(value: any) {
this.theme = value
localStorage.setItem('theme', value)
},
/**
* 切换颜色
* @param value value
*/
setTagColor(value: any) {
this.themeColor = value
document.documentElement.style.setProperty('--themeColor', value)
localStorage.setItem('themeColor', value)
},
/**
* 灰色模式
* @param value value
*/
setGrey(value: any) {
this.isGrey = !this.isGrey
const body = document.body
body.removeAttribute('style')
if (!value) return
body.setAttribute('style', 'filter: grayscale(1)')
},
/**
* 模块坞图标
*/
setModuleUnfoldIcon() {
this.moduleUnfoldIconOpen = !this.moduleUnfoldIconOpen
},
/**
* 显示LOGO
*/
setLogo() {
this.logoOpen = !this.logoOpen
},
/**
* 初始化主题色
*/
initThemeColor() {
document.documentElement.style.setProperty(
'--themeColor',
this.themeColor,
)
},
/**
* 展开折叠菜单
*/
setMenusState() {
this.collapsed = !this.collapsed
},
},
})
app.vue
<template>
<a-config-provider
:locale="zhCN"
:theme="{
token: {
colorPrimary: useGlobalStore().themeColor,
},
}"
>
<vue3-progress-bar></vue3-progress-bar>
<router-view></router-view>
</a-config-provider>
</template>
<script lang="ts" setup>
import { useGlobalStore } from '@/stores/global'
useGlobalStore().initThemeColor()
</script>
<style lang="less">
@import '@/style/theme.css';
#app {
/* app style */
.vue3-progress-bar-container {
.vue3-progress-bar {
background-color: var(--themeColor);
}
}
a {
color: var(--themeColor);
}
}
</style>
效果图