赞
踩
本系列只讲项目实战,前期搭建请自行参考官方文档
基于 css-vars-ponyfill
实现一键换肤功能
屏幕录制2023-09-05 16.37.39
# yarn add css-vars-ponyfill 或
npm i css-vars-ponyfill
在 src/
创建 theme
目录
创建 src/theme/index.ts
// theme.js import { blueTheme, darkTheme, greenTheme, vermilionTheme } from "./variable"; import cssVars from "css-vars-ponyfill"; // 返回主题配色 export const getTheme = (theme: string, color: string):any => { switch(theme) { case "blue": blueTheme["--primary-text-color"] = color; return blueTheme; case "dark": darkTheme["--primary-text-color"] = color; return darkTheme; case "green": greenTheme["--primary-text-color"] = color; return greenTheme; case "vermilion": vermilionTheme["--primary-text-color"] = color; return vermilionTheme; } } export const initTheme = (theme: any, color: string) => { document.documentElement.setAttribute("data-theme", theme); cssVars({ watch: true, // 当添加,删除或修改其<link>或<style>元素的禁用或href属性时,ponyfill将自行调用 variables: getTheme(theme, color), // variables 自定义属性名/值对的集合 onlyLegacy: false, // false 默认将css变量编译为浏览器识别的css样式 true 当浏览器不支持css变量的时候将css变量编译为识别的css }); };
创建 src/theme/variable.ts
我这里是创建了四套样式,可以根据自己的UI作调整
// 字体变量 const baseSize = { "--font-size-large-x": "22px", "--font-size-large": "18px", "--font-size-medium": "14px", "--font-size-medium-x": "16px", "--font-size-small-s": "10px", "--font-size-small": "12px", }; // 钴蓝 export const blueTheme = { // 菜单栏 颜色 "--menu-bg": "#2f3447", "--logo-bg": "#2f3447", "--logo-text-color": "#fff", "--menu-actvie-bg": "#1890ff", "--menu-hover-bg": "#1890ff", "--menu-text-color": "#fff", "--menu-active-text-color": "#fff", "--menu-hover-text-color": "#fff", // 顶部导航栏 颜色 "--header-bg": "#fff", "--header-text-color": "#333", "--header-hover-text-color": "#1890ff", // 内容区域配色 "--border-color": "#dcdfe6", // 主色系 "--primary-text-color": "#2f3447", ...baseSize } // 极黑 export const darkTheme = { // 菜单栏 颜色 "--menu-bg": "#2f3447", "--logo-bg": "#2f3447", "--logo-text-color": "#fff", "--menu-actvie-bg": "#222222", "--menu-hover-bg": "#222222", "--menu-text-color": "#eee", "--menu-active-text-color": "#eee", "--menu-hover-text-color": "#eee", // 顶部导航栏 颜色 "--header-bg": "#2f3447", "--header-text-color": "#eee", "--header-hover-text-color": "#222222", // 内容区域配色 "--border-color": "#dcdfe6", "--primary-text-color": "#eee", ...baseSize } // 果绿 export const greenTheme = { // 菜单栏 颜色 "--menu-bg": "#fff", "--logo-bg": "#51c21a", "--logo-text-color": "#fff", "--menu-actvie-bg": "#fff", "--menu-hover-bg": "#fff", "--menu-text-color": "#333", "--menu-active-text-color": "#51c21a", "--menu-hover-text-color": "#51c21a", // 顶部导航栏 颜色 "--header-bg": "#fff", "--header-text-color": "#333", "--header-hover-text-color": "#333", "--primary-text-color": "#51c21a", // 内容区域配色 "--border-color": "#dcdfe6", ...baseSize } // 朱砂色 export const vermilionTheme = { // 菜单栏 颜色 "--menu-bg": "#fff", "--logo-bg": "#e9692b", "--logo-text-color": "#fff", "--menu-actvie-bg": "#fff", "--menu-hover-bg": "#fff", "--menu-text-color": "#333", "--menu-active-text-color": "#e9692b", "--menu-hover-text-color": "#e9692b", // 顶部导航栏 颜色 "--header-bg": "#fff", "--header-text-color": "#333", "--header-hover-text-color": "#e9692b", "--primary-text-color": "#e9692b", // 内容区域配色 "--border-color": "#dcdfe6", ...baseSize }
项目中使用
App.vue
<template> <router-view v-slot="{ Component }"> <keep-alive> <a-config-provider prefix-cls="custom"> <component :is="Component"></component> </a-config-provider> </keep-alive> </router-view> </template> <script setup lang="ts"> // 用的仓库是 Pinia 也可以使用其他库比如 Vuex import { themeStore } from "./store/theme"; // AntDVue 中修改主题的API 其他库也有类似的 根据自己项目中实际的库做变更 import { ConfigProvider } from 'ant-design-vue'; // 上边定义的 initTheme 方法 import { initTheme } from "@/theme"; // 主题仓库 const store = themeStore(); // 修改Antd主题 const initThemeConfig = (color: string) => { ConfigProvider.config({ prefixCls: 'custom', theme: { // 成功相关主题颜色 primaryColor: color, errorColor: "#FF4D4F", warningColor: "#FAAD14", successColor: "#52C41A", infoColor: "#57595C", }, }); } // 初始化调用一次 initThemeConfig(store.getPrimary); // 初始化自定义主题 全局样式变量切换 initTheme(store.getThemeType, store.getPrimary); // 监听到样式发生改变,切换主题 store.$subscribe((mutations, state) => { initThemeConfig(state.primaryColor); initTheme(state.themeType, state.primaryColor) }) </script> <style></style>
src/store/theme.ts
import { defineStore } from "pinia"; interface themeInter { primaryColor: string, themeType: string } export const themeStore = defineStore("theme", { state: ():themeInter => { return { // 主色系 primaryColor: "#1890ff", // 主题色 Key 对应 src/theme/variable.ts 中声明的变量 themeType: "blue" }; }, getters: { getPrimary(): string { return this.primaryColor; }, getThemeType(): string { return this.themeType; } }, // 同步和异步都可以写 actions: { setPrimary(color: string) { this.primaryColor = color; }, setThemeType(type: string) { this.themeType = type; } }, })
到这里你已经成功掌握了一键换肤
https://gitee.com/KeLuKeYa/vue3-test#project-setup
本系列持续更新,后续功能会持续更新到次仓库
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。