现在越来越多的网站支持主题切换,我们的也要!
在这,我们要实现两个例子,主题切换与夜间模式!
主题切换:
夜间模式:
1、准备工作,初始化一个简单的vite项目
安装 ant-design-vue和less
yarn add ant-design-vue@next yarn add less --save
因为ant-design-vue是使用less开发的,所以既然用了它,咱最好还是用和它一致的less。
在main.ts中全局引入antd组件与样式
import { createApp } from 'vue' import App from './App.vue' import Antd from 'ant-design-vue'; import 'ant-design-vue/dist/antd.less' createApp(App).use(Antd).mount('#app')
在App.vue中,我们将无用代码去掉,加入一些antd的按钮便于测试。
<template> <a-button type="primary">Primary Button</a-button> <a-button>Default Button</a-button> <a-button type="dashed">Dashed Button</a-button> <a-button type="text">Text Button</a-button> <a-button type="link">Link Button</a-button> </template>
使用yarn dev
启动
发现报错,原因是,我们引入的样式是less
文件,我们需要在vite.config.ts
文件中开启支持。
import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' export default defineConfig({ plugins: [vue()], // 开启less支持 css: { preprocessorOptions: { less: { javascriptEnabled: true } } } })
重新启动
2、切换主题
别嫌前面啰嗦,了解它创建的步骤,才能不跳坑。不然以后掉坑了也不知道怎么回事,比如上面的开启less支持…
官网上对于主题的切换是有说明的:https://next.antdv.com/docs/vue/customize-theme-cn
也就是说我们可以通过修改这些less变量,达到我们定制化主题的目标。
官网虽然没有提供vite方式修改主题的说明,但是举了vue cli ,webpack的例子,其实我们也能知道了,在vite中是差不多的,都是通过less中的modifyVars
进行修改。试试
css: { preprocessorOptions: { less: { modifyVars: { 'primary-color': '#1DA57A', 'link-color': '#1DA57A', 'border-radius-base': '2px', }, javascriptEnabled: true } } }
注意,这里都是字符串形式的键值对。
看一下主题,确实改变了。
但是这只是静态的。咱想要实现的是,动态切换我们的主题,如何实现?
3、动态切换主题
这里我使用一个vite插件:vite-plugin-theme-preprocessor
一个vite v2.0+插件,用于实现多个 less、sass 变量文件编译出多主题的 css,使得基于less、sass以及css modules的主题样式在线动态切换变得很简单。
原帖地址:传送门
根据仓库中的说明,我们需要先安装插件:
yarn add @zougt/vite-plugin-theme-preprocessor -D yarn add path --save
注意 path
是用来解析路径的,这在我们项目中很多地方都会用得到,同样。这里也需要。
然后我们需要在vite.config.ts中使用这个插件。
import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import path from 'path' import themePreprocessorPlugin from "@zougt/vite-plugin-theme-preprocessor"; export default defineConfig({ plugins: [ vue(), themePreprocessorPlugin({ less: { // 各个主题文件的位置 multipleScopeVars: [ { scopeName: "theme-default", path: path.resolve("src/theme/default.less"), }, { scopeName: "theme-green", path: path.resolve("src/theme/green.less"), }, ], }, }), ], // 开启less支持 css: { preprocessorOptions: { less: { modifyVars: { 'primary-color': '#1DA57A', 'link-color': '#1DA57A', 'border-radius-base': '2px', }, javascriptEnabled: true } } } })
上面,我们定义了两个主题分别是:theme-default与 theme-green以及对应得主题文件得位置。
我们切换主题就靠主题文件了。
接下来我们需要创建这两个主题文件,并分别引入ant的样式文件,注意是less格式。
@import "ant-design-vue/lib/style/themes/default.less"; // defalut.less // 上面引入了核心样式文件,我们可以对其进行修改,覆盖原来的达到我们的目的。 // 这里不仅能修改变量还能修改样式 // 比如我修改以下 // 全局主色 黄色 @primary-color: #ffa618; // 链接色 青色 @link-color: #18ffb2; @import "ant-design-vue/lib/style/themes/default.less"; // green.less // 全局主色 绿色 @primary-color: #1cce42; // 链接色 粉红色 @link-color: #c76f98;
注意:ant-design-vue/lib/style/themes/default.less
这个路径是没有问题的,如果报错了,请检查你有没有安装easy less
这个插件,有的话,禁用掉!
然后,我们就可以进行主题切换的逻辑了!
我们逻辑比较简单,我使用一个开关,打开是绿色,关闭是黄色。
在App.vue中
<template> <a-button type="primary">Primary Button</a-button> <a-button>Default Button</a-button> <a-button type="dashed">Dashed Button</a-button> <a-button type="text">Text Button</a-button> <a-button type="link">Link Button</a-button> <!-- 开关切换主题 --> <a-switch v-model:checked="checked" checked-children="绿" un-checked-children="黄" @change="change" /> </template> <script lang="ts"> import { defineComponent, ref } from "vue"; import { toggleTheme } from "@zougt/vite-plugin-theme-preprocessor/dist/browser-utils.js"; export default defineComponent({ setup() { const checked = ref<boolean>(false); // 切换主题回调 const change = (value: boolean) => { // 如果开关打开,就切换为绿色主题,否则默认黄色主题 if (value) { toggleTheme({ scopeName: "theme-green", }); console.log("已切换为绿色主题"); } else { toggleTheme({ scopeName: "theme-default", }); console.log("已切换为默认主题"); } }; return { checked, change, }; }, }); </script>
注意:如果你引入插件的时候报错了,但其实这并不是错,你需要关闭ts的严格检查模式。也就是在tsconfig.json中"strict": false,
然后注意,这时候切换主题发现是无效的。
还记得你在vite.config.ts中自定义的主题吗,将其删掉或注释掉,因为它的优先级比较高。
css: { preprocessorOptions: { less: { // modifyVars: { // 'primary-color': '#1DA57A', // 'link-color': '#1DA57A', // 'border-radius-base': '2px', // }, javascriptEnabled: true } } }
这时候,我们片头的效果就出来了。
4、夜间模式
这个有了前面的铺垫就很简单了,官方实现了一套暗黑主题,我们将green.less
修改一下。
// @import "ant-design-vue/lib/style/themes/default.less"; // 修改为暗黑主题 @import "ant-design-vue/lib/style/themes/dark.less"; // 全局主色 绿色 @primary-color: #1cce42; // 链接色 粉红色 @link-color: #c76f98;
其他的也不用变
对于这类组件库来说,如果没有提供类似的暗黑模式,可能就需要一点点去改了,那耗费的时间将是相当巨大的。
5、总结
上面的主题切换不仅仅是对于ant-design-vue适用,还对所有的基于less和sass的适用,用法都是一样的。
在这之前我们看多许多主题切换的方案,CSS变量、antd-theme-generator、还有一堆webpack的,但是这都不是我所需要的,有幸最终找到了ZGT大佬写的vite-plugin-theme-preprocessor
,确实是达到了我的期望。