常见Vue UI框架的在线主题切换

您所在的位置:网站首页 vue框架使用方法 常见Vue UI框架的在线主题切换

常见Vue UI框架的在线主题切换

#常见Vue UI框架的在线主题切换| 来源: 网络整理| 查看: 265

在如今,很多网页已经可以手动切换明亮模式和黑暗模式,网页的主题切换已经成为了一个常用的需求,因此,本文将从常见框架的处理方式总结一些相关的操作,并探究其本质。

AntD 的方式

AntD 的 config-provider​ 似乎不能直接修改主题,目前网络上的教程有两类,一类是通过 less 的修改变量修改来完成,另一类是操作 DOM 改变对文件的引用,由于 ant-design-vue 已经提供了黑暗主题,而且直接修改 less 文件的变量涉及到了太多变量,不太方便,因此参考了 @杭州程序员张张的文章,使用动态添加 CSS 引用 DOM 的方式实现黑暗主题的切换,原理是添加一个 DOM,引用我们自定义的 CSS 样式,后面的引用会覆盖前面的引用,在切换到亮色主题时把这个 DOM 删除。

1. 创建黑暗主题文件

在目录下的适当位置创建一个黑暗主题的文件,后面要引用这个文件,这里直接把官方黑暗主题复制过来就可以了,它的位置在 node_modules/ant-design-vue/dist/antd.dark.min.css​,假设我们把它复制到了 public/styles/dark.css ​中。

2. 创建切换主题的函数

有了主题文件,我们就可以创建切换主题的函数了,在目录中的合适位置创建一个 js 文件,例如 src/utils/theme.ts​,其中的代码为:

const darkThemeSwitch = () => { // id要与前面一致 const theme_element = document.querySelector('#dark-theme-style'); if (!theme_element) { const new_dark_Theme = document.createElement('link') new_dark_Theme.setAttribute('rel', 'stylesheet'); //刚刚设置的css路径 new_dark_Theme.setAttribute('href', '/styles/dark.css'); // id可以自由设置 new_dark_Theme.setAttribute('id', 'dark-theme-style'); const docHead = document.querySelector('head'); docHead?.append(new_dark_Theme); } else { const parentNode = theme_element?.parentNode; parentNode?.removeChild(theme_element); } } export default darkThemeSwitch; 3. 切换主题

然后,我们在需要切换主题的地方使用这个方法就可以了:

切换主题 import darkThemeSwitch from '../utils/theme'; const toggleDark = () => { darkThemeSwitch(); }; Quasar 的方式

quasar 的主题切换非常简单,只要使用 quasar 官方提供的 dark 插件就可以了,使用方法如下:

import { useQuasar } from 'quasar' const $q = useQuasar() // get status console.log($q.dark.isActive) // true, false // get configured status console.log($q.dark.mode) // "auto", true, false // set status $q.dark.set(true) // or false or "auto" // toggle $q.dark.toggle()

通过研究 Quasar 的源码,可以发现,Quasar 的黑暗有两种设置方式,自动和手动,在自动模式下,插件通过监听 prefers-color-scheme: dark​ 的状态来决定当前网页的主题,通过这种方式,可以实现网页跟随系统主题自动变换浅色和深色模式,对应部分的代码如下:

Plugin.mode = val if (val === 'auto') { if (Plugin.__media === void 0) { Plugin.__media = window.matchMedia('(prefers-color-scheme: dark)') Plugin.__updateMedia = () => { Plugin.set('auto') } Plugin.__media.addListener(Plugin.__updateMedia) } val = Plugin.__media.matches }

上面的代码中,Plugin.mode ​代表设置方式,Plugin.__media ​的值默认就是 void 0​,这里的判断的作用是当第一次执行时给相应的 Media 添加一个监听来获得实时的变化。这里调用的 Plugin.set('auto') ​就是手动设置的函数,这个函数接受一个布尔值,然后根据布尔值的真假对主题进行设置,相应的实现如下:

document.body.classList.remove(`body--${ val === true ? 'light' : 'dark' }`) document.body.classList.add(`body--${ val === true ? 'dark' : 'light' }`)

显然,这里的实现方式也比较常规,即在 body 标签添加或删除相应的样式选择器类名来实现主题的切换,quasar 值得我们学习的地方在于它把所有的功能集成到 useQuasar ​中,用户可以方便地使用各种插件,而不需要写很多代码。完整的代码如下:

import defineReactivePlugin from '../utils/private/define-reactive-plugin.js' import { isRuntimeSsrPreHydration } from './Platform.js' const Plugin = defineReactivePlugin({ // 插件的属性 isActive: false, mode: false }, { __media: void 0, // 插件的核心方法 set(val) { if (__QUASAR_SSR_SERVER__) { return } Plugin.mode = val // 自动主题切换 if (val === 'auto') { if (Plugin.__media === void 0) { Plugin.__media = window.matchMedia('(prefers-color-scheme: dark)') Plugin.__updateMedia = () => { Plugin.set('auto') } Plugin.__media.addListener(Plugin.__updateMedia) } val = Plugin.__media.matches } else if (Plugin.__media !== void 0) { Plugin.__media.removeListener(Plugin.__updateMedia) Plugin.__media = void 0 } Plugin.isActive = val === true // 手动指定主题 document.body.classList.remove(`body--${val === true ? 'light' : 'dark'}`) document.body.classList.add(`body--${val === true ? 'dark' : 'light'}`) }, // 主题的切换 toggle() { if (__QUASAR_SSR_SERVER__ !== true) { Plugin.set(Plugin.isActive === false) } }, install({ $q, onSSRHydrated, ssrContext }) { const { dark } = $q.config if (__QUASAR_SSR_SERVER__) { this.isActive = dark === true $q.dark = { isActive: false, mode: false, set: val => { ssrContext._meta.bodyClasses = ssrContext._meta.bodyClasses .replace(' body--light', '') .replace(' body--dark', '') + ` body--${val === true ? 'dark' : 'light'}` $q.dark.isActive = val === true $q.dark.mode = val }, toggle: () => { $q.dark.set($q.dark.isActive === false) } } $q.dark.set(dark) return } $q.dark = this if (this.__installed === true && dark === void 0) { return } this.isActive = dark === true const initialVal = dark !== void 0 ? dark : false if (isRuntimeSsrPreHydration.value === true) { const ssrSet = val => { this.__fromSSR = val } const originalSet = this.set this.set = ssrSet ssrSet(initialVal) onSSRHydrated.push(() => { this.set = originalSet this.set(this.__fromSSR) }) } else { this.set(initialVal) } } }) export default Plugin ElementUI 的方式

在 2.2.0 版本,Element UI 也可以进行黑暗模式切换了,操作如下:

在 main.ts ​引入官方的 CSS:import 'element-plus/theme-chalk/dark/css-vars.css'​更改 html​ 标签的类,添加 dark​ 即为黑暗模式,去掉 dark 即为明亮模式,这一过程有很多实现方法,官方推荐使用 VueUse​ 这个函数库中的 useDark​ 来实现,这是一个非常强大的官方工具库,里面提供了许多常用功能的实现以及一些小插件,非常值得学习,请参考VueUse官方文档。import { useDark, useToggle } from '@vueuse/core'; const isDark = useDark(); const toggleDark = useToggle(isDark); NaiveUI 的方式

NaiveUI 的黑暗主题是通过其提供的 Config Provider ​组件来实现的,通过设置其 theme ​属性为 null ​或者 darkTheme​(需要从 naive-ui 导入),可以更改其内部组件的主题,配合 Global Style ​组件,可以设置全局的主题:

深色 浅色 import { ref } from 'vue' import { darkTheme } from 'naive-ui' import type { GlobalTheme } from 'naive-ui' const theme = ref(null)

还可以通过 useOsTheme ​获取系统的主题作为组件的主题:

当前操作系统的主题是 {{ osTheme }}。 import { defineComponent, computed } from 'vue' import { useOsTheme, darkTheme } from 'naive-ui' export default defineComponent({ setup () { const osThemeRef = useOsTheme() return { theme: computed(() => (osThemeRef.value === 'dark' ? darkTheme : null)), osTheme: osThemeRef } } })



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3