当前位置: 首页 > news >正文

Vue学习记录之二十七 Pinia的使用

Pinia 是一个用于 Vue.js 的状态管理库,旨在取代 Vuex,提供更现代的 API 和更好的开发体验。

一、安装

pnpm install pinia -s  //运行时依赖

二、配置

在 main.ts中

import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'  //导入依赖
const store = createPinia()
let app = createApp(App)
app.use(store)                      //注册组件
app.mount('#app')

三、创建一个 Store

src/store/index.ts

import { defineStore } from 'pinia'
import {Names} from './store-name'
export const useTestStore = defineStore(Names.TEST,{state:()=>{return {current: 20,name: "lvmanba"}},//computed 修饰一些值getters:{doubleCount: (state) => state.current * 2,},//methods 可以做同步,异步都可以做。提交stateactions:{setCurrent(num:number){this.current = num}}})// 热重载支持
if (import.meta.hot) {import.meta.hot.accept((newModule) => {useCounterStore.hotUpdate(newModule.useCounterStore);});
}

src/store/store-name.ts

export const enum Names{ //定义了一个名为Names的枚举TEST = 'TEST'
}

四、使用

<template><div>demo</div><div>pinia:{{Test.current}} - {{Test.name}}</div><div>{{ Test.doubleCount }}</div><div><button @click="change">修改pinia中的current</button></div>
</template>
<script setup lang='ts'>
import { ref,reactive } from 'vue'
import { useTestStore } from './store/index'
const Test = useTestStore()
// 方法1
/*
const change = () => {Test.current++
}
*/
// 方法2 通过patch
/*
const change = () => {Test.$patch({current: 888,name: "绿曼巴"})
}
*/
// 方法3, 还是使用patch, 他接收一个工厂函数,里面可以处理逻辑
/*
const change = () =>{Test.$patch((state)=>{ //state 就是我们pinia中的state.state.current++state.name = '方世玉'})
}
*/
// 方法4,不常用,有弊端,修改的话,需要修改整个对象,必须修改所有的值
/*
const change = () => {Test.$state = {current:2000,name:"少年没有乌托邦,心向远方自明朗"}
}
*/
// 方法5  使用defineStore定义的store中的action中的方法const change = () => {Test.setCurrent(567)
}</script>
<style scoped></style>

五、实例

代码的结构和上面一样: 功能是实现同步和异步调用。
App.vue

<template><div>demo<p> aciions-user: {{ Test.user}}</p><hr /><p> aciions-name: {{ Test.name}}</p><hr /><p> getters: {{ Test.newName}}</p><hr><button @click="change">修改pinia中的current</button></div>
</template>
<script setup lang='ts'>
import { ref,reactive } from 'vue'
import { useTestStore } from './store/index'
const Test = useTestStore()const change = () => {Test.setUser()
}
</script>
<style scoped></style>

src/store/index.ts

import { defineStore } from 'pinia'
import {Names} from './store-name'type User = {name: string,age:number
}
/*
// 同步
let result:User = {name:"飞机",age: 18
}
*/const Login = ():Promise<User> => {return new Promise((resolve)=>{setTimeout(()=>{resolve({name: 'lmb',age: 42})},2000)})
}export const useTestStore = defineStore(Names.TEST,{state:()=>{return {user:<User>{},name: "小飞机"}},//computed 修饰一些值getters:{newName():string{  //需要设置返回值类型,要不报错。return `$-${this.name}-${this.getUserAge}`},getUserAge():number{return this.user.age}},//methods 可以做同步,异步都可以做。提交stateactions:{async setUser(){const result = await Login();this.user = result;this.setName('大飞机')},setName(name:string){this.name = name}}})

六、Pinia的API

1、$reset()

调用reset可以让值恢复到state定义的原始值
如在App.vue

<template><div><button @click="reset">reset</button></div>
</template>
<script setup lang='ts'>
import { ref,reactive } from 'vue'
import { useTestStore } from './store/index'
const Test = useTestStore()const reset = () => {Test.$reset()
}
</script>

2、$subscribe

$subscribe 方法用于监听 store 中状态的变化,只要发生变化,就自动调用。它接受一个回调函数,该函数会在每次 store 状态发生变化时被调用。回调函数有两个参数:

  • mutation:一个对象,包含关于状态变化的信息。典型的字段包括 storeId(store 的 ID)、type(变化的类型,例如 patch 或 direct)、events(变化的详细信息)。
  • state:变化后的新状态。
const unsubscribe = Test.$subscribe((mutation, state) => {console.log(mutation);  // mutation 是一个描述状态变化的对象console.log(state);     // state 是变化后的新状态
});// 如果你想取消订阅,可以调用 unsubscribe 函数
unsubscribe();

3、$onAction

$onAction 是一个方法,用于监听 store 中 action 的调用。通过这个方法,你可以在 action 被调用之前和之后执行一些代码,比如记录日志、性能监控或错误处理等。

const off = store.$onAction(({ name, store, args, after, onError }) => {console.log(`Action ${name} was called with args:`, args);// 在 action 执行后执行一些代码。一个函数,接受一个回调函数,该回调函数会在 action 执行完毕后被调用,并传入 action 的返回值。after((result) => {console.log(`Action ${name} finished with result:`, result);});// 在 action 执行时发生错误时执行一些代码onError((error) => {console.error(`Action ${name} failed with error:`, error);});
});// 如果你想取消监听,可以调用 off 函数
off();

七、常见的问题

1、Pinia 支持热重载,但是需要单独设置,你可以在开发过程中修改 store 而无需刷新整个页面:

if (import.meta.hot) {import.meta.hot.accept(acceptHMRUpdate(useCounterStore, import.meta.hot));
}

2、解构出来的变量不具备响应性,需要用到storeToRefs

import { storeToRefs } from 'pinia'
// const {current,name} = Test
// 这样current,name就具备了响应式
const {current,name} = storeToRefs(Test)

八、持久化

pinia和vuex 都有一个通病页面刷新状态会丢失。我们可以写一个pinia插件缓存他的值。
可以使用 pinia-plugin-persist 插件。这个插件允许你将状态存储到 LocalStorage 或 SessionStorage 中,从而在页面刷新后保留状态。

npm install pinia pinia-plugin-persist

配置

import { createApp } from 'vue';
import { createPinia } from 'pinia';
import piniaPersist from 'pinia-plugin-persist';  //导入依赖
import App from './App.vue';const app = createApp(App);
const pinia = createPinia();pinia.use(piniaPersist);  //注册插件app.use(pinia);
app.mount('#app');

使用:

import { defineStore } from 'pinia';export const useMainStore = defineStore({id: 'main',state: () => ({counter: 0,user: {name: 'John Doe',age: 30}}),actions: {increment() {this.counter++;},setUser(name, age) {this.user.name = name;this.user.age = age;}},persist: {enabled: true,strategies: [{key: 'main_store',storage: localStorage, // 你也可以使用 sessionStorage},],},
});

读取存储

<template><div><p>Counter: {{ counter }}</p><button @click="increment">Increment</button></div>
</template><script setup lang="ts">
import { useMainStore } from './stores/main';// 获取 store 实例
const mainStore = useMainStore();// 解构需要的状态和方法
const { counter, increment } = mainStore;
</script>

http://www.mrgr.cn/news/62333.html

相关文章:

  • Hbase的特点、特性
  • RCE简介
  • 【Unity3D】Particle粒子特效或3D物体显示在UGUI上的方案
  • AI 技术,让洗护行业焕然「衣」新
  • Python读取Excel批量写入到PPT生成词卡
  • C++ OpenGL学习笔记(4、绘制贴图纹理)
  • 97、Python并发编程:多线程实现的两种方式
  • 串口屏控制的自动滑轨
  • 【MySQL】 运维篇—安全管理:数据加密与SSL配置
  • Java基础2-数组
  • Python | Leetcode Python题解之第521题最长特殊序列I
  • C语言 | Leetcode C语言题解之第522题最长特殊序列II
  • C++ | Leetcode C++题解之第522题最长特殊序列II
  • 【多线程场景下事务失效问题如何处理?】
  • 从openjdk17 C++源码角度看 java类成员变量是怎么赋值的
  • 理解环境变量与Shell编程:Linux开发的基础
  • DS18B20+测量系统可编程分辨率高精度数字温度传感器芯片
  • Python——石头剪刀布(附源码+多模式二改优化版)
  • C++学习笔记----9、发现继承的技巧(六)---- 有趣且令人迷惑的继承问题(6)
  • <HarmonyOS第一课>给应用添加通知和提醒的习题
  • VC2012创建弹出式菜单
  • 智能进阶之路:从基础模型到个性化代理—探索Agent与微调的共生之道
  • [专有网络VPC]创建和管理流量镜像
  • 神奇的数据恢复工具:让丢失的数据重现
  • 线上 Dump
  • 【数据结构】链表详解:数据节点的链接原理