vite实现element-plus按需配置,自定义主题和读取/修改系统主题色
vite.config.ts 插件和vite配置
import { defineConfig } from "vite"; import vue from "@vitejs/plugin-vue"; import path from "path"; import vueJsx from "@vitejs/plugin-vue-jsx"; import AutoImport from "unplugin-auto-import/vite"; import Pages from "vite-plugin-pages"; import Components from "unplugin-vue-components/vite"; import { ElementPlusResolver } from "unplugin-vue-components/resolvers"; import ElementPlus from "unplugin-element-plus/vite"; import Inspect from "vite-plugin-inspect"; // https://vitejs.dev/config/ export default defineConfig({ plugins: [ vue(), vueJsx({ // options are passed on to @vue/babel-plugin-jsx }), AutoImport({ imports: ["vue", "vue-router"], dts: "./auto-imports.d.ts", eslintrc: { enabled: true, // Default `false` filepath: "./.eslintrc-auto-import.json", // Default `./.eslintrc-auto-import.json` globalsPropValue: true, // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable') }, resolvers: [ElementPlusResolver({ importStyle: "sass" })], }), Components({ resolvers: [ElementPlusResolver({ importStyle: "sass" })], dts: true, include: [/\.vue$/, /\.vue\?vue/, /\.tsx$/], //默认自动导入src/components下的组件 }), Pages({ ... }), ElementPlus({ useSource: true, }), Inspect(), ], resolve: { alias: { "@": "/src", "~/": `${path.resolve(__dirname, "src")}/`, }, }, css: { preprocessorOptions: { scss: { additionalData: `@use "~/styles/element/index.scss" as *;`, }, }, }, });
styles/element/index.scss 修改变量的文件
/** @format */ @use "sass:map"; $--colors: ( "primary": ( "base": #93040b, ), ); @forward "element-plus/theme-chalk/src/common/var.scss" with ( $colors: $--colors, $carousel: ( "indicator-width": 6px, "indicator-height": 6px, "indicator-padding-horizontal": 4px, "indicator-padding-vertical": 12px, "indicator-out-color": map.get($--colors, "primary", "base"), ) );
vite-env.d.ts
/// <reference types="vite/client" /> /// <reference types="vite-plugin-pages/client" />
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
配合媒体查询,检测用户是否设置了系统主题,重写:root下的css变量
:root {
color-scheme: light dark;
}
/* 监听操作系统主题模式 */
@media (prefers-color-scheme: dark) {
body {
background-color: var(--color-background);
}
}
@media (prefers-color-scheme: light) {
body {
background-color: var(--white-color-background);
}
}
使用媒体查询,可以查看当前是否是暗色主题:
window.matchMedia("(prefers-color-scheme: dark)");
以下是一个跟随系统色/改变系统色/自定义主题色的简单例子
<style> * { margin: 0; padding: 0; text-align: center; } :root { color-scheme: dark light; } @media (prefers-color-scheme: dark) { :root { color-scheme: dark; --bg-color: #414141; --border-color: #000000; --hightlight-color: green; /* 修改:checked 的选中颜色 默认是 `auto`,系统高亮色 注释掉此行,选中时的颜色就是你定义的系统高亮色 */ accent-color: var(--hightlight-color); } :focus { outline: auto 2px green; } } @media (prefers-color-scheme: light) { :root { --bg-color: #ffffff; } } body.beauty { --bg-color: #cf23ff; } </style> </head> <body class="" style="height:100vh;background-color: var(--bg-color);"> <input type="radio" name="" id=""> <input type="checkbox" name="" id=""> <input type="text" name="" id=""> </body>
在element-plus项目中,需要覆盖变量
@media (prefers-color-scheme: dark) { html:root { color-scheme: dark; --el-text-color-primary: #ffffff; } } @media (prefers-color-scheme: light) { html:root { color-scheme: light; --el-color-black: #333333; } }
element-plus官网给的方案是在html上添加dark类名,在项目中创建个响应变量去修改css变量,可以添加很多种配色方案吧。
document.querySelector(':root').computedStyleMap().get("--el-text-color-primary")
补充element-plus网站的代码
(() => { const e = localStorage.getItem("el-theme-appearance"); (e === "auto" ? window.matchMedia("(prefers-color-scheme: dark)").matches : e === "dark") && document.documentElement.classList.add("dark"); })();
zhangxinxu推荐的网站换肤的最佳实现
利用link标签 rel属性。特点就是,预加载了其他主题,实现无缝切换。