vue3 实现主题色以及修改主题色

目录

前言

主题色切换

1.设置默认主题

2.点击切换主题

3.切换主题色的原理

自定义主题

总结


前言

使用的模板:https://github.com/jzfai/vue3-admin-ts

迁移项目到新项目的时候,需要改系统的主题颜色,这个模板里可以选择主题颜色,组件大小,和系统语言,这里就取消能修改主题颜色的功能,默认的是base-theme,于是查看了文档,找到主题是这部分的内容,前言 | vue3-admin-plus
发现如果自定义一套主题,其实原理并不难,下面写我看过这个功能后,自己理解的实现该功能的详细的过程。vue3 实现主题色以及修改主题色_第1张图片

主题色切换

假如我们有主题色三个,每一个主题肯定都有一个ID,比如:base-theme/lighting-theme/dark-theme

1.设置默认主题

如果实现切换,那么肯定有一个默认的值,假设默认的主题是base-theme。这种默认的配置一般会和设置系统语言,设置组件大小,设置系统名称等静态配置放到一个settings里。

src\settings.js 

import packageJson from '../package.json'
export const settings = {
  title: packageJson.name,
  
  /*
   * i18n setting default language
   * en/zh
   * */
  defaultLanguage: 'zh',
  /*
   *  default theme
   * base-theme/lighting-theme/dark-theme
   * */
  defaultTheme: 'base-theme',
  /*
   * setting default defaultSize
   * large / default /small
   * */
  defaultSize: 'default',
  
}

export default settings

 有了默认的主题色,那么修改主题色肯定有一个方法,将这个settings的值覆盖掉,至于怎么覆盖并怎么改变系统的颜色是之后考虑的。

2.点击切换主题

什么时候需要切换主题:一个是Vue初始化时,读取默认的主题,一个是页面配置主题选项,点击时调用这个方法,去切换主题。如果这个方法是setTheme,那么需要一个参数,主题id。

既然有这个方法存在,那么显然一般这种全局的方法,肯定都是写在store里。

src\store\config.ts

import { defineStore } from 'pinia'
import { langTitle } from '@/hooks/use-common'
import settings from '@/settings'
import { toggleHtmlClass } from '@/theme/utils'
import { i18n } from '@/lang'
export const useConfigStore = defineStore('config', {
  state: () => {
    return {
      language: settings.defaultLanguage,
      theme: settings.defaultTheme,
      size: settings.defaultSize
    }
  },
  persist: {
    storage: localStorage,
    paths: ['language', 'theme', 'size']
  },
  actions: {
    // 切换主题色————这里
    setTheme(data: string) {
      this.theme = data
      toggleHtmlClass(data)
    },
    //设置组件大小
    setSize(data: string) {
      this.size = data
    },
    // 设置系统语言
    setLanguage(lang: string, title) {
      const { locale }: any = i18n.global
      this.language = lang
      locale.value = lang
      document.title = langTitle(title) // i18 page title
    }
  }
})

这里的theme先读的是默认的主题颜色,如果页面需要切换主题,传一个主题色并存起来,用到persist来保持持久化。
 

persist是将 Vuex store 中的一些状态(languagethemesize)保存到浏览器的 localStorage 中,以便在页面刷新后能够保留这些状态的值。

  • storage: localStorage:表示使用浏览器的 localStorage 作为持久化存储,保存的数据在页面刷新或关闭后仍然存在。

  • paths: ['language', 'theme', 'size']:指定了需要持久化的状态路径。在你的 Vuex store 中,这包括了 languagetheme、和 size 这三个状态。这意味着只有这些状态的变化会被保存到 localStorage 中,其他状态不会被持久化。

这个配置的好处在于,当用户刷新页面或关闭再打开页面时,之前存储在 localStorage 中的状态值会被还原到 Vuex store 中,使应用程序能够保持之前的状态。这对于用户体验和记住用户的个性化设置非常有用,因为用户在一次会话中所做的更改不会因为刷新页面而丢失。Vue3 有了这个可以方便地进行持久化存储。

加了这个配置的效果如下:

vue3 实现主题色以及修改主题色_第2张图片

至于在哪里切换主题颜色,可以在app.vue的onMounted里先执行一下,读取一下默认主题,之后如果页面需要,就同样地在页面加切换主题色的功能,但是都是setTheme来执行。

上面是指怎么切换主题颜色,如何实现真正切换主题是通过toggleHtmlClass,这个涉及css的一些东西,下面详细讲解主题色实现的过程。 

3.切换主题色的原理

这里以默认的base-theme为例子来讲。

这里有模板的文档对于主题色实现的原理的解释,如:

vue3 实现主题色以及修改主题色_第3张图片

在CSS3中,:root是伪类,文档的根元素,比如,我们都知道HTML文件里,HTML文件是根元素,如果 :root定义一个全局变量,那么全局都能用,通过 var() 函数引用它们。这种方式使得可以在一个地方定义主题或颜色变量,然后在整个样式表中方便地引用这些变量,实现一致性的主题设计。

需要注意的是,:root 只是一个约定用法,也可以选择其他选择器来定义全局变量,但通常 :root 是最常见的选择,因为它表示文档的根元素,所以我猜测这个模板实现主题色切换的原理就是通过html的类名,然后更改主题色。

HTML 文档中 标签的类名可以接受一个类名 className 作为参数,然后将 标签的类名设置为这个参数值。

通过操作 标签的类名,可以实现一些在整个页面中生效的样式变更或主题切换。

例如,如果在 CSS 中定义了与特定类名相关的样式规则,那么通过切换 标签的类名,可以在整个页面上切换不同的样式或主题。

这是一个简单的示例,假设你有两个不同的样式主题,一个是深色主题,一个是浅色主题:

// 切换到深色主题 toggleHtmlClass('dark-theme'); 
// 切换到浅色主题 toggleHtmlClass('light-theme'); 

在这个例子中,toggleHtmlClass 函数的调用会改变 标签的类名,从而触发不同主题的样式规则。这是一种在整个应用程序中切换主题或样式的通用方式。

比如,我选中一个组件,查看它的类,发现这里就有主题的类名存在:

vue3 实现主题色以及修改主题色_第4张图片

当我切换主题时,我发现这个类名也随之改变了,那么就清楚实现的原理了。核心代码是这一段:

export const toggleHtmlClass = (className) => {
  document.querySelectorAll('html')[0].className = className
}

 这段代码主要是切换 HTML 文档中 标签的类名。

  • document.querySelectorAll('html'):使用 document.querySelectorAll 方法选择所有 标签。该方法返回一个 NodeList(节点列表),通过 [0] 取得第一个匹配的 元素。

  • .className = className:将 元素的类名设置为传入函数的参数 className。这意味着这个函数的目的是动态地改变整个页面的样式,通过修改 标签的类名来触发不同的 CSS 样式规则。

就如上面所述,这样就可以切换主题了。

具体如何自定义主题的颜色等样式,这里有一个模板的代码可以查看。 

自定义主题

这里以base-theme为例子,主要的颜色都没有改,因为用的是模块里封装好的自定义主体,所以改起来很容易,后面有时间再详细地了解一下实现过程。

vue3 实现主题色以及修改主题色_第5张图片

vue3 实现主题色以及修改主题色_第6张图片

具体的代码,可以看模板里的代码。开头有链接和地址。实现原理在开头的文档里,写的很详细就不多阐述了。

总结

总算了解了一些实现系统主题色的方法,虽然很多细节尚未掌握,但是简单的主题颜色已经能快速地掌握修改啦,over~

你可能感兴趣的:(vue2,升级,Vue3,项目迁移,javascript,前端,typescript)