vue3 antd 自定义切换主题色

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'

猜你喜欢

转载自blog.csdn.net/weixin_45653441/article/details/131985344