vue中使用 pinia 全局状态管理的实现

目录
  • 与vuex的区别
  • 安装
  • 引入pinia
  • 创建状态目录
  • pinia模块组成
  • 创建pinia模块
  • 在组件中使用该状态机
  • pinia模块实例中的api讲解
  • 状态持久化

与vuex的区别

去除了 mutation 选项。省去了复杂的disptachcommit流程,直接通过模块实例调用实例的actions中的方法即可触发对应action;在组件中直接可以通过模块实例的$patch修改store状态或者通过action来间接修改store状态。响应式数据原理是proxy,使得数据的增加或者删除字段都具备响应式。

安装

yarn add pinia

引入pinia

main.ts中注册pinia插件

import {createPinia} from 'pinia'    // vue3
// import {PiniaVuePlugin} from 'pinia' // vue2

const app=createApp(App)
app.use(createPinia())
app.mount('#app')

创建状态目录

在src下创建文件夹store,在store下创建文件index.ts,a.ts,b.ts。a.ts和b.ts分别是管理某个状态的模块,index.ts用来整合这些模块。

pinia模块组成

state、actions、getters。

创建pinia模块

对应选项的含义看代码注释。
1.在a.js编写如下代码

import {defineStore} from "pinia"

export default defineStore('a',{    // a是模块的命名空间,不能和其他模块的一样
    state:()=>({         // state是一个函数,函数返回值为管理的状态
        x:0,
        y:0,
    }),
 })

2.在b.ts编写如下代码

import {defineStore} from "pinia"

export default defineStore('b',{
    state:()=>({
        name:'b',
        age:18,
    }),
    actions:{
        print(msg:string){     // 同步action
            console.log(msg)
         },
        async setAge(newAge:number){       // 异步action
            // 模拟接口
            const setAgeReq=<T>(age:T)=>new Promise<T>((rel)=>{
                setTimeout(()=>{rel(age)},1000)
            })

            const age=await setAgeReq(newAge)
            // 在action中通过实例来直接修改状态
            this.age=age
            // 在action中也可以通过实例直接调用其他action
            // this.print('age is be updated success')
        }
    },
    getters:{
        // 和vuex的getters一样,返回一个值就行了。和computed一样具有缓存机制
        userInfo():string{
            return `name:${this.name} age:${this.age}`
        }
    },

})

3.在index.ts中整合所有模块

import a from "./a"
import b from "./b"

export {
   a,b
}

在组件中使用该状态机

pinia的api基本都在该案例中,注释和代码都很容易理解,相信小伙伴们都看的懂。如果不是很明白,可以看下一章节的api讲解,看懂的可以跳过api讲解章节。

<script setup lang='ts'>
// 引入pinia模块
import {a as useA ,b as useB} from "./store"
import {storeToRefs} from "pinia" 

// 模块是一个函数,函数的返回值是模块的实例
const storeA=useA()
const storeB=useB()

/* 通过$patch直接修改store状态,$patch方法接收一个函数,函数的参数是该模块的状态
在这个函数中我们可以直接修改store状态*/
const addx=()=>{storeA.$patch((s)=>{s.x++})}
const addy=()=>{storeA.$patch((s)=>{s.y++})}
// 如果要解构使用状态需要使用该api进行转换,否则不具备响应式
const {x,y}=storeToRefs(useA())

// 通过action间接修改store状态
const setAge=()=>{
 // 异步action返回promise。原理也很简单,async函数的返回值是promise
 storeB.setAge(20).then(()=>{console.log('age is be updated success')})
}

// 通过 $subscribe监听状态的变更
storeB.$subscribe((c,s)=>{  // state变化时回调。有变化信息和状态两个参数
//    console.log(c)
//    console.log(s)
},{
	detached:false,  // 在组件卸载时是否继续监听
	deep:true,  // 是否深度监听
	flush:'post',  // post:组件更新后执行;sync:始终同步触发;pre:组件更新前执行
})

// 通过$onAction监听action的调用
storeB.$onAction((c)=>{   // 当调用action时回调
    // console.log(c)
    // c.after(()=>{console.log('after caller')})  //after的回调在该函数中最后执行
    // console.log('action')
},false)   // 为true时,组件卸载时也监听该行为

// 通过$reset重置对应模块的状态
const reSetAge=()=>{
   storeB.$reset()
}

</script>

<template>
	<h3>模块a</h3>
	<p>({{storeA.x}},{{storeA.y}})</p>
	<button @click="addx">x++</button>
	<button @click="addy">y++</button>
	<h3>模块b</h3>
	<p>用户信息:{{storeB.userInfo}}</p>
	<button @click="setAge">setAge</button>
	<button @click="reSetAge">reSetAge</button>

</template>

运行结果:

pinia模块实例中的api讲解

1.获取模块实例

// 引入模块
import {a as useA ,b as useB} from "./store"  

// 模块是一个函数,函数的返回值是模块的实例
const storeA=useA()
const storeB=useB()

2.提供实例修改对应模块的状态
i:直接修改

/* 通过$patch直接修改store状态,$patch方法接收一个函数,函数的参数是该模块的状态
在这个函数中我们可以直接修改store状态*/
const addx=()=>{storeA.$patch((s)=>{s.x++})}
const addy=()=>{storeA.$patch((s)=>{s.y++})}

ii:间接修改

import {storeToRefs} from "pinia"
// 如果要解构使用状态需要使用该api进行转换,否则不具备响应式
const {x,y}=storeToRefs(useA())

3.状态的解构使用

import {storeToRefs} from "pinia"
// 如果要解构使用状态需要使用该api进行转换,否则不具备响应式
const {x,y}=storeToRefs(useA())

4.监听状态的变更

// 通过 $subscribe监听状态的变更
storeB.$subscribe((c,s)=>{  // state变化时回调。有变化信息和状态两个参数
//    console.log(c)
//    console.log(s)
},{
detached:false,  // 在组件卸载时是否继续监听
deep:true,  // 是否深度监听
flush:'post',  // post:组件更新后执行   ,sync:始终同步触发     ,pre:组件更新前执行
})

5.监听action的触发

// 通过$onAction监听action的调用
storeB.$onAction((c)=>{   // 当调用action时回调
    // console.log(c)
    // c.after(()=>{console.log('after caller')})  //after的回调在该函数中最后执行
    // console.log('action')
},false)   // 为true时,组件卸载时也监听该行为

6.重置状态

// 通过$reset重置对应模块的状态
const reSetAge=()=>{
   storeB.$reset()
}

7.注册插件

import {createPinia} from 'pinia'
// plugin是一个函数
createPinia().use(Plugin)

状态持久化

这里需要使用到注册插件的功能。首先在src/plugins/pinia/persistence.ts中编写如下代码

import {PiniaPluginContext} from 'pinia'
import {toRaw } from 'vue' 

// 封装pinia持久化插件。执行时机:store初始化时,执行次数是模块的次数
export default function(type:'localStorage' | 'sessionStorage'){

    return (ctx:PiniaPluginContext)=>{
       //    console.log(ctx)
   // const {app,options,pinia,store}=ctx
   /*
      app:vue应用 ;options:导出pinia模块的选项
      pinia:pinia app ; store:pinia的store实例
   */
   const store= ctx.store    // 每次执行时的store是关于那个模块的store
   const storeWay=type==='localStorage'?localStorage:sessionStorage
   // console.log(store)
   store.$subscribe(()=>{
      // console.log(toRaw(store.$state))

      storeWay.setItem('pinia_'+store.$id,JSON.stringify(toRaw(store.$state)))
   },{deep:true})

    // return的值为store初始状态。pinia处理过了,如果为retrun为null使用模块的初始值,
    return JSON.parse(storeWay.getItem('pinia_'+store.$id) as any)
    }
}

然后在mian.js编写如下代码即可。此时刷新浏览器刷新时,状态是可以保持的,不会被重置。

import { createApp} from 'vue'
import App from './App.vue'
import {createPinia} from 'pinia'
// import {PiniaVuePlugin} from 'pinia' // vue2
import persistence from "./plugins/pinia/persistence"

const app=createApp(App)

// app.use(createPinia().use(persistence('sessionStorage')))   //sessionStorage方式持久化
app.use(createPinia().use(persistence('localStorage')))  //localStorage方式持久化

app.mount('#app')

到此这篇关于vue中使用 pinia 全局状态管理的实现的文章就介绍到这了,更多相关vue pinia 全局状态管理内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Vue状态管理之使用Pinia代替Vuex

    目录 1.Pinia是什么 2.Pinia简单上手 3.使用体验 1.Pinia是什么 Pinia是一个vue的状态管理方案,是vuex团队成员开发,实现了很多vuex5的提案,更加地轻量化且有devtools的支持 vuex4一直被人诟病对于typescript的支持不良好,vuex5也迟迟未来 所以有了pinia的出现 相较于vuex: pinia无需创建复杂的包装器来支持typescript,对于typescript类型判断是天然支持的,享受ide带来的自动补全,减少开发的心智负担,减少v

  • 还在用vuex?来了解一下pinia

    目录 1.什么是pinia 2.优势 3.使用(非常简单) 总结 1. 什么是pinia 通俗的讲 : ① vuex精简版 ,而且vue官方更加推荐使用. ②优势又完胜于vuex ,下面我们来了解下pinia. 2.优势 pina vuex pinia 同时支持vue2和vue3 vue2要用vuex 3 版本vue3要用vuex 4 版本 不分同步异步,更好的ts支持 分同步异步,不太兼容ts 享受自动补全… 需要注入,导入函数,调用他们… 3. 使用 (非常简单) ① 安装 npm inst

  • vue3中vuex与pinia的踩坑笔记记录

    目录 介绍 安装使用 简单对比写法差异与共同点 Vuex 和 Pinia 的优缺点 何时使用Pinia,何时使用Vuex 总结 介绍 Pinia 是 Vue.js 的轻量级状态管理库,最近很受欢迎.它使用 Vue 3 中的新反应系统来构建一个直观且完全类型化的状态管理库. Pinia的成功可以归功于其管理存储数据的独特功能(可扩展性.存储模块组织.状态变化分组.多存储创建等). 另一方面,Vuex也是为Vue框架建立的一个流行的状态管理库,它也是Vue核心团队推荐的状态管理库.Vuex高度关注应

  • Vue3状态管理之Pinia的入门使用教程

    目录 Vue3 新的发展方向(来源于尤大知乎) 一.Pinia 简介与基础 1.1 Pinia 简介 1.2 Pinia 基础 二.Pinia 在Vue3-Vite中的使用 2.1 基础使用流程 2.2 state 中数据的解构访问 2.3 state 中数据的修改方式(actions和组件中) 2.4 getters 的使用 三.Pinia 数据持久化 总结 Vue3 新的发展方向(来源于尤大知乎) Vue 3 将在 2022 年 2 月 7 日 成为新的默认版本 基于 Vite 的极速构建工

  • Vue生态的新成员Pinia的详细介绍

    目录 安装和配置 Store核心 State Getters Actions Vue Devtools 最后 结论 参考文献 Pinia是Vue应用程序的状态管理方案,是Vuex核心团队成员开发.感觉更像是常规的旧 javascript 导入模块,实现了很多Vuex5的提案. Pinia同时支持Vue2和Vue3,不过下面展示的例子都是使用Vue3,Pinia的版本是Pinia@2.0.9. Vue2和Vue3使用的Pinia版本有一点不同,因此请查看官方Pinia 文档以获取更多信息. 安装和

  • Vue新的状态管理库Pinia入门教程

    目录 前沿 使用教程 1.安装 2.vue中引入 3.基本使用 4.也可以像vuex一样使用 为什么最近Pinia会火起来呢,主要在于Vue3推出来的时候,Vuex对于Vue3的组合式Api支持的不是特别好,也就是在这个时候Pinia出现了. 前沿 Vue官方推荐的状态管理库是Vuex,那为什么最近Pinia会火起来呢,主要在于Vue3推出来的时候,Vuex对于Vue3的组合式Api支持的不是特别好,也就是在这个时候Pinia出现了,最重要的是,Pinia不但支持Vue3,同时还支持Vue2,这

  • vue3搭配pinia的踩坑实战记录

    目录 前言 An Object could not be cloned? VUE 3的toRaw PINIA与VUE 3可以混合搭配? 同样的操作在VUE 3下的结果 最后的解决方式 总结 前言 最近接手了一个新项目,用的是VUE3+pinia的组合.由于之前没有用过这2个库,只能现学现做.幸运的是这两者的上手难度都不大,项目可以正常开发.但这其中也遇到了一些坑,今天就来讲其中我印象最深的一个. An Object could not be cloned? 不知道有多少开发者遇到过这个报错——A

  • Vue新一代状态管理工具Pinia的具体使用

    目录 前言 优点 安装 创建并挂载 创建store 使用store 回显与修改state 使用$patch对多条数据直接修改 使用actions 使用getters 多个store相互调用 数据持久化 安装 使用 总结 前言 Pinia是尤雨溪强烈推荐的一款Vue状态管理工具,也被认为是下一代Vuex的替代产品. 优点 去除了mutations,只有 state,getters和actions,其中actions支持了同步和异步操作 不会像Vuex那样有模块嵌套,Pinia只有store的概念,

  • vue中使用 pinia 全局状态管理的实现

    目录 与vuex的区别 安装 引入pinia 创建状态目录 pinia模块组成 创建pinia模块 在组件中使用该状态机 pinia模块实例中的api讲解 状态持久化 与vuex的区别 去除了 mutation 选项.省去了复杂的disptach和commit流程,直接通过模块实例调用实例的actions中的方法即可触发对应action:在组件中直接可以通过模块实例的$patch修改store状态或者通过action来间接修改store状态.响应式数据原理是proxy,使得数据的增加或者删除字段

  • React全局状态管理的三种底层机制探究

    目录 前言 props context state 总结 前言 现代前端框架都是基于组件的方式来开发页面.按照逻辑关系把页面划分为不同的组件,分别开发不同的组件,然后把它们一层层组装起来,把根组件传入 ReactDOM.render 或者 vue 的 $mount 方法中,就会遍历整个组件树渲染成对应的 dom. 组件都支持传递一些参数来定制,也可以在内部保存一些交互状态,并且会在参数和状态变化以后自动的重新渲染对应部分的 dom. 虽然从逻辑上划分成了不同的组件,但它们都是同一个应用的不同部分

  • Pinia.js状态管理器上手使用指南

    目录 前言 安装 创建 Store State 定义State 获取 state 修改 state Getters Actions 异步 action action 间相互调用 数据持久化 安装 使用 自定义 key 持久化部分 state 最后 前言 Pinia.js 是新一代的状态管理器,由 Vue.js团队中成员所开发的,因此也被认为是下一代的 Vuex,即 Vuex5.x,在 Vue3.0 的项目中使用也是备受推崇. Pinia.js 有如下特点: 完整的 typescript 的支持:

  • vue中使用router全局守卫实现页面拦截的示例

    一.背景 在vue项目中使用vue-router做页面跳转时,路由的方式有两种,一种是静态路由,另一种是动态路由.而要实现对路由的控制需要使用vuex和router全局守卫进行判断拦截(安全问题文章最后讨论) 二.使用场景 静态路由的使用场景:在我们使用静态路由实现页面跳转时,不管我们是否登录,当我们在地址栏修改地址后,页面会发生跳转并展示页面内容(数据并不会被展示出来),这样的问题显然是不能够被接受的: 动态路由的使用场景:动态路由无非就是从后端拿到了数据然后在加到router里面了.假如用户

  • 微信小程序MoxB实现全局状态管理流程详解

    目录 安装 MobX 创建 MobX Store 使用 MobX Store 在 Component 构造器中使用 在 Page 页面中使用 github 地址:https://github.com/wechat-miniprogram/mobx-miniprogram-bindings. 安装 MobX 在小程序根目录下执行 npm install --save mobx-miniprogram mobx-miniprogram-bindings 安装 mobx-miniprogram 和 m

  • vue中npm包全局安装和局部安装过程

    全局安装是将npm包安装在你的node安装目录下的node_modules文件夹中.在windows和mac中,全局安装的默认路径是不同的.在mac中默认是安装到 /usr/locla/lib 中.在windows默认安装目录是 C:\Program Files\nodejs ,当然你也可以通过一下命令来查看全局安装路径. // 查看全局安装路径 npm root -g // 查看npm的基础设置 npm config ls // 查看安装目录路径 npm config get prefix 全

  • 详解vue组件化开发-vuex状态管理库

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化.Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试.状态快照导入导出等高级调试功能. 以上是vuex的官方文档对vuex的介绍,官方文档对vuex的用法进行了详细的说明.这里就不再细讲vuex的各个用法,写这篇博客的目的只是帮助部分同学更快地理解并上手vuex.

  • Vue中的验证登录状态的实现方法

    Vue项目中实现用户登录及token验证 先说一下我的实现步骤: 使用easy-mock新建登录接口,模拟用户数据 使用axios请求登录接口,匹配账号和密码 账号密码验证后, 拿到token,将token存储到sessionStorage中,并跳转到首页 前端每次跳转时,就使用导航守卫(vue-router.beforeEach)判断 sessionStorage 中有无 token ,没有就跳转到登录页面,有则跳转到对应路由页面. 注销后,就清除sessionStorage里的token信息

  • 快速掌握Vue3.0中如何上手Vuex状态管理

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化.Vuex 也集成到 Vue 的官方调试工具 devtools,提供了诸如零配置的 time-travel 调试.状态快照导入导出等高级调试功能. 如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的.确实是如此--如果您的应用够简单,您最好不要使用 Vuex.一个简单的 store 模式就足够您所需了.但是,如果您需要构建一个中大型

  • 在Vue中实现添加全局store

    目录 Vue添加全局store 在命令行中输入安装 在main.js文件中引用 在src中创建一个page文件 在src下创建一个store文件 store使用方法讲解 vuex 包含有五个基本的对象 vuex,module间的方法调用 vue文件调用store的action方法 Vue添加全局store 在命令行中输入安装 npm install --save vuex 在main.js文件中引用 store和在new Vue中声明store import store from './stor

随机推荐