vue3 antd 自定义切换主题色
切换颜色hook文件 统一管理
import { onBeforeMount } from 'vue'
import { ConfigProvider } from 'ant-design-vue'
const LOCAL_THEME = 'local_theme'
const LOCAL_PAGE = 'local_page'
// export const colors: string[] = [
// '#f5222d',
// '#fa541c',
// '#fa8c16',
// '#a0d911',
// '#13c2c2',
// '#1890ff',
// '#722ed1',
// '#eb2f96',
// '#faad14',
// '#52c41a',
// ];
export const useUserTheme = () => {
onBeforeMount(() => {
apply(load())
createPageColor()
})
}
export const randomTheme = (color: string) => {
return color
}
export const createPageColor = () => {
const themePage = localStorage.getItem(LOCAL_PAGE) || 'dark'
localStorage.setItem(LOCAL_PAGE, themePage)
}
export const load = () => {
const color = localStorage.getItem(LOCAL_THEME) || '#1890ff'
return color
}
export const save = (color: string) => {
localStorage.setItem(LOCAL_THEME, color)
}
export const apply = (color: string) => {
ConfigProvider.config({
theme: {
primaryColor: color
}
})
save(color)
}
主题切换组件 theme.vue 在layout组件里使用
<template>
<div class="flex">
<transition name="fade">
<div class="color" v-show="show">
<a-tooltip class="colorBlock" v-for="item in colors" :key="item">
<!-- <template #title>{
{ item}}</template> -->
<a-tag :color="item" @click="changeColor(item)">
<CheckOutlined v-if="colorBg === item" />
</a-tag>
</a-tooltip>
</div>
</transition>
<div @click="showDiv">
<a style="padding: 0; display: inline-block; user-select: none">
<BgColorsOutlined :style="{ fontSize: '18px' }" />
</a>
</div>
<div style="margin-left: 20px">
<a-popover title="">
<template #content>
<h4>风格设置</h4>
<div class="blockChecbox">
<a-tooltip v-for="(item, index) in themeList" :key="index" placement="top">
<template #title>
<span>{
{ item.tips }}</span>
</template>
<div class="theme" @click="handleMenuTheme(item.value)">
<a-avatar :src="item.image" :alt="item.value" shape="square" />
<check-outlined v-if="modelValue == item.value" class="selectIcon" />
</div>
</a-tooltip>
</div>
</template>
<ControlOutlined :style="{ fontSize: '18px' }" :rotate="90" />
</a-popover>
</div>
</div>
</template>
<script setup lang="ts">
import { BgColorsOutlined, CheckOutlined, ControlOutlined } from '@ant-design/icons-vue'
import { apply, randomTheme } from '@/hooks/useTheme'
import { ref } from 'vue'
import { useCounterStore } from '@/stores/counter'
let store = useCounterStore()
const show = ref<any>(false)
const showDiv = () => {
show.value = !show.value
}
let colorBg = ref<string>(localStorage.local_theme)
const colors: string[] = [
'#f5222d',
'#fa541c',
'#fa8c16',
'#a0d911',
'#13c2c2',
'#1890ff',
'#722ed1',
'#eb2f96',
'#faad14',
'#52c41a'
]
import darkImg from '/public/dark.svg'
import lightImg from '/public/light.svg'
const themeList = [
{
tips: '暗色主题风格',
value: 'dark',
image: darkImg
},
{
tips: '亮色主题风格',
value: 'light',
image: lightImg
}
]
let modelValue = ref<string>(localStorage.local_page)
const handleMenuTheme = (value: string) => {
console.log(value)
modelValue.value = value
localStorage.local_page = value
store.local_page = value
}
const changeColor = (item: string) => {
apply(randomTheme(item))
colorBg.value = localStorage.local_theme
show.value = !show.value
store.local_theme = item
}
</script>
<style scoped lang="scss">
.flex {
display: flex;
align-items: center;
}
.color {
margin-right: 20px;
}
.colorBlock {
width: 20px;
height: 20px;
border-radius: 2px;
float: left;
cursor: pointer;
margin-right: 8px;
padding-left: 0px;
padding-right: 0px;
text-align: center;
color: #fff;
font-weight: 700;
i {
font-size: 14px;
}
}
.fade-leave {
opacity: 1;
}
.fade-leave-active {
transition: all 0.5s;
}
.fade-leave-to {
opacity: 0;
}
.blockChecbox {
display: flex;
.theme {
margin-right: 20px;
position: relative;
border-radius: 4px;
cursor: pointer;
.selectIcon {
position: absolute;
top: 0px;
right: 5px;
width: 100%;
padding-top: 15px;
padding-left: 24px;
height: 100%;
color: #1890ff;
font-size: 14px;
}
}
}
</style>
在appvue里使用
<script setup lang="ts">
import { ConfigProvider } from 'ant-design-vue'
import { RouterView } from 'vue-router'
import zh_CN from 'ant-design-vue/es/locale/zh_CN'
import { useUserTheme } from '@/hooks/useTheme'
useUserTheme()
</script>
<template>
<ConfigProvider :locale="zh_CN">
<RouterView />
</ConfigProvider>
</template>
maints引入antd css
import 'ant-design-vue/dist/antd.variable.min.css'