vue Pinia 全局主题切换


vue Pinia 全局主题切换

目的 : 实现单页面上切换主题,例如 关灯或开灯;

环境: vue3.0 + vite + Pinia

基本环境
// tsconfig.json 文件中 新增路径配置 导入自定义文件时可以之间@导入
{
  "compilerOptions": {
	"baseUrl": "./",
    "paths": {
      "@/*":["src/*"]
    }
  },
}
// main.ts
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import { createPinia } from 'pinia'
import router from '@/router/router'


// 创建app为vue实例根组件或全局组件;
const app = createApp(App)
// vue实例添加router组件
app.use(router)
// vue实例添加pinia组件
app.use(createPinia())
// vue实例挂载到index.html页面
app.mount('#app')

// app.vue
<script setup lang="ts">
// 导入引入的组件
import { NConfigProvider,NGlobalStyle, zhCN, dateZhCN,useOsTheme} from 'naive-ui'
import {useThemeStore} from '@/store/theme'
// themeStore 主题实例
const themeStore = useThemeStore()
</script>

<template>
  <!-- 全局处理 颜色组件 -->
  <n-config-provider 
    :theme="themeStore.theme"
    :locale="zhCN"
    :date-locale="dateZhCN">
    	<!-- 组件渲染出口 -->
    	<router-view></router-view>
    <n-global-style />
  </n-config-provider>
</template>

默认路由router加载 /路径,所以新建了一个index.vue用来组装页面;

// ViewHead.vue 页面 头部组件,导入到index.vue中
<script lang="ts" setup>
import { onMounted,ref,reactive,computed,onBeforeMount,onUpdated,onUnmounted,watch} from 'vue';
import {NButton,useOsTheme} from 'naive-ui'
import { update } from 'lodash';
import {useThemeStore} from '@/store/theme'
// 主题标记
const themeFlag=ref(true)
// themeStore
const theme = useThemeStore()
// 获取当前系统主题
const osTheme = useOsTheme();
// 监听当前操作系统主题
watch(osTheme,osTheme=>{
    if(osTheme){
        if(osTheme==="dark"){
          themeFlag.value=true
        }else{
          themeFlag.value=false
        }
        updateTheme()
    }
},{
    // 第一次绑定时会初始化立即执行一次
    immediate:true
})
// 变更主题
function updateTheme(){
        themeFlag.value=!themeFlag.value
        theme.setTheme(themeFlag.value);
}
</script>
<template>
    <h2>测试{{ "haha" }}</h2>
    <n-button  @click="updateTheme" strong secondary type="success">
      {{themeFlag?"光明":"黑暗"}}
    </n-button>
</template>
<style lang="less" scoped>

</style>

Pinia Store 组件的使用,用来缓存主题的全局状态

import {darkTheme,lightTheme} from 'naive-ui'
import { defineStore } from 'pinia'
import { ref, watch} from 'vue'
import type {GlobalTheme} from 'naive-ui'

// themeStore of pinia
export const useThemeStore = defineStore('themeStore',()=>{
    // theme ref var
    const theme = ref<GlobalTheme>(lightTheme)
    // actions: update Theme 
    function setTheme(themes:boolean){
        if(themes){
            // true lightTheme
            theme.value  = lightTheme
        }else{
            // false darkTheme
            theme.value  = darkTheme
        }
    }

    return {
        theme,
        setTheme
    }
})

目录结构

src
├─api
├─assets
├─components
├─router
├─store
	├─theme.ts
├─view
	├─fixedcomponent
		├─ViewHead.vue
	├─index.vue
App.vue
main.ts
结果展示

开灯效果
关灯效果

过程解析

因为使用了NaiveUI所以就使用了其支持的全局化配置Config Provider 即: App.vue 中的<n-config-provider>标签 ,包裹整个页面的渲染出口;

因为触发切换的组件在ViewHead.vue子组件内所以需要使用 Pinia store theme.ts来存储全局的主题状态变化和主题变更的触发;

ViewHead.vue中使用 n-button 按钮即可 通过 useThemeStore()中的setTheme()方法修改其theme的状态属性, 进而改变n-config-provider 标签的:theme属性

实现初次加载页面时根据系统的主题来修改页面的theme主题状态, 在ViewHead.vue中通过watch监听useOsTheme()即可实现;

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue Pinia 是一个状态管理库,可以用来管理 Vue.js 应用程序中的状态。下面是使用 Vue Pinia 的一些基本步骤: 1. 安装 Vue Pinia 你可以通过 npm 或 yarn 来安装 Vue Pinia: ``` npm install pinia ``` 或者 ``` yarn add pinia ``` 2. 创建 Pinia 实例 在 Vue 应用程序的入口文件中,创建一个 Pinia 实例,并将其挂载到 Vue 实例中: ```javascript import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' const pinia = createPinia() const app = createApp(App) app.use(pinia) app.mount('#app') ``` 3. 定义状态 使用 `defineStore` 方法来定义状态: ```javascript import { defineStore } from 'pinia' export const useCounterStore = defineStore({ id: 'counter', state: () => ({ count: 0 }), actions: { increment() { this.count++ } } }) ``` 在上面的示例中,我们定义了一个名为 `useCounterStore` 的状态库,其中包含一个名为 `count` 的状态和一个名为 `increment` 的操作。 4. 在组件中使用状态 使用 `useStore` 方法来在组件中使用状态: ```javascript import { defineComponent } from 'vue' import { useCounterStore } from './store' export default defineComponent({ setup() { const counterStore = useCounterStore() return { count: counterStore.count, increment: counterStore.increment } } }) ``` 在上面的示例中,我们在组件中使用了名为 `useCounterStore` 的状态库,并从中获取了 `count` 和 `increment` 状态。 这些是使用 Vue Pinia 的基本步骤。当然,Vue Pinia 还有许多其他功能,例如插件和插件选项,可以帮助你更好地管理 Vue.js 应用程序中的状态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值