电商网站建设文献,精简wordpress博客程序,注册网站如何备案,智能网站搭建平台Vue3 官推的状态管理 Pinia 一、Pinia是什么#xff1f;二、Pinia的特点三、Pinia的使用1.npm install pinia -s2.创建pinia实例3.注册到App实例上4.模块化管理5.组件中使用6.路由中使用1.创建全局路由守卫2.全局守卫中使用全局状态 四、修改数据 $patch五、重置数据 $reset六… Vue3 官推的状态管理 Pinia 一、Pinia是什么二、Pinia的特点三、Pinia的使用1.npm install pinia -s2.创建pinia实例3.注册到App实例上4.模块化管理5.组件中使用6.路由中使用1.创建全局路由守卫2.全局守卫中使用全局状态 四、修改数据 $patch五、重置数据 $reset六、监听数据 $subscribe七、监听Actions $onAction()Tip可以在pinia实例上使用watch()函数侦听整个state。Tip不使用setup时。 一、Pinia是什么
在Vue2中一般采用Vuex进行状态管理在Vue3中推荐使用Pinia,这Vue3中推荐使用Pinia这是最新一代轻量级状态管理插件。Vuex将不再接受新的功能。推荐使用Pinia。
二、Pinia的特点
支持Vue2和Vue3两者都可以使用Pinia语法简洁支持Vue3中的setup的写法不必像Vue2中那样定义state、mutations、actions、getters等可以按照setup Composition API的方式返回状态和改变状态的方法实现代码的扁平化;支持Vuex中state、actions、getters形式的写法丢弃了mutations开发时候不用根据同步异步来决定mutation或者actionsPinia中只有actions对TyppeScript支持非常友好
三、Pinia的使用
1.npm install pinia -s
2.创建pinia实例
// src/store/index.ts
import { createPinia } from pinia;const pinia createPinia();
export default pinia ;3.注册到App实例上
// src/main.ts
import App from ./App.vue;
import { createApp } from vue;
import pinia from /store;const app createApp(App);
app.use(pinia);4.模块化管理
defineStore方法的第一个参数为仓库起一个名字呢不可重复唯一的 defineStore方法的第二个参数有setup和option两种写法
// src/store/modules/demo.tssetup写法
import { defineStore } from pinia;
import { store } from //store;const useDemoStore defineStore(demo,(){const counter ref(0);const increment (){counter.value;}return {counter,increment}
});
export default useDemoStore;// src/store/modules/demo.tsoption写法
import { defineStore } from pinia;
import { store } from //store;export const useDemoStore defineStore(demo,{state:(){return {name:张三,count:0}},getters:{getName:(state){// return this.namegetName;return state.namegetName;return (id)state.list.filter(vv.idid);//getters传参}},actions:{updateName:(val:string){this.nameval;}},persist:true
});state:用来存储全局的状态这边定义的可以全局访问 getters:和Vuex一样来监视或者计算状态变化具有缓存功能组件中调用多次实际在store中只执行了一次 actions:适合处理修改逻辑复杂的数据可以在actions中定义好函数然后在组件中调用是state数据相关的业务逻辑需求不同逻辑不同。 注getters和actions里可以直接使用this。
5.组件中使用
// src/views/Demo.vue
templateh1counter:{{counter}}/h1el-button clickadd 自增 /el-button
/template
script setup langtsimport { storeToRefs} from pinia;import useDemoStore from //store/modules/demo.ts;const demoStore useDemoStore();const { counter } storeToRefs(demoStore);const add (){demoStore.increment();}console.log(demoStore.getName());
/script注无论是pinia还是vuex通过解构的方式获取状态会导致状态失去响应性。如 const { counter } demoStore; 此时counter丢失了响应性当其值发生改变时其他组件不会监听到。所以pinia提供了storeToRefs函数使其解构出来的状态仍然具有相应性。 const { counter } storeToRefs(demoStore); 6.路由中使用
演示在全局路由守卫中获取状态值。创建一个路由守卫在路由守卫中使用nprogress显示页面加载进度。
1.创建全局路由守卫
安装nprogress npm install nprogress npm install types/nprogress -D 创建全局路由守卫
// src\router\guard\index.ts
import nProgress from nprogress;
import nprogress/nprogress.css;
nProgress.configure({showspinner:false,
})
// 全局前置守卫
router.beforeEach((to,from){nProgress.start();return true;
})
// 全局后置守卫
router.afterEach((to,from){nProgress.done(true);
})3.在main.ts中引入全局守卫路由
import /router/guard/index2.全局守卫中使用全局状态
实际开发中路由切换时可能需要从全局状态中获取token等信息判断是否能进入下一页面。
// src\router\guard\index.ts
...
import useDemoStore from /store/modules/demo
import {storeToRefs} from pinia
...
const demoStore useDemoStore();
const {counter} storeToRefs(demoStore);
// 全局前置守卫
router.beforeEach((to,from){nProgress.start();console.log(counter);return true;
})在钩子函数外pinia还没有挂载所以会报错应该修改后如下
// src\router\guard\index.ts
import router from /router;
import nProgress from nprogress;
import nprogress/nprogress.css;
import useDemoStore from /store/modules/demo
import {storeToRefs} from pinia
nProgress.configure({showspinner:false,
})
// 全局前置守卫
router.beforeEach((to,from){nProgress.start();const demoStore useDemoStore();const {counter} storeToRefs(demoStore);console.log(counter);return true;
})
// 全局后置守卫
router.afterEach((to,from){nProgress.done(true);
})# 四、Pinia状态持久化## 1.为什么需要状态持久化
因为状态存储到浏览器内存中刷新浏览器后重新加载页面会重新初始化vue.pinia,导致浏览器存储中的数据丢失。
实际项目中,浏览器刷新时这有些数据希望保存下来。
解决方案状态改变时将其同步到浏览器的存储中如cookie,localStorage,sessionStorage,每次初始化状态时从存储中获取初始值即可。
## 2.插件pinia-plugin-persistedstate1. npm install pinia-plugin-persistedstate 2. src/store/index.ts
typescript
import { createPinia } from pinia;
import piniaPluginPersistedState from pinia-plugin-persistedstate;const pinia createPinia();
pinia.use(piniaPluginPersistedState);
export default pinia;模块管理中的使用
// src/store/modules/demo.ts
import { defineStore } from pinia;
import { store } from //store;const useDemoStore defineStore(demo,(){const counter ref(0);const increment (){counter.value;}return {counter,increment}
},{ persist:true });
export default useDemoStore;persist : 值为true状态存储在localStorage中该localStorage中的key为模块名“demo”。 如何修改key如何将状态存储到SessionStorage
{persist:{key:byyourself,storage:sessionStorage,}
}四、修改数据 $patch
const updataName () {// 1.修改单个数据demoStore.name李四;// 2.修改多个数据-$patchdemoStore.$patch({name:李四,count:18)// 3.修改复杂数据-$patch函数demoStore.$patch((state){state.name李四;})// 4.使用action处理数据demoStore.updateName(李四)
}五、重置数据 $reset
const resetName (){demoStore.$reset();
}pinia setup 方式构建$reset方法失效解决方案
import { creatPinia } from pinia;
const pinia creatPinia();
pinia.use((store){const initialStataJSON.parse(JSON.stringify(store.$state));store.$reset(){store.$patch(initialStata)}
})六、监听数据 $subscribe const subscribeName demoStore.$subscribe((mutations,state){// 监听store中的某个值变化处理一些逻辑// $subscribe第一个参数mutations包含了3个属性// 1.events改变的具体数据newValue,oldValue;// 2.storeId:当前store的Id,这里是demo;// 3.type:记录改变数据途径direct通过actions改变patch object:// 提供$patch传递的方式改变的patch function:通过$patch传递函数// $subscribe第二参数是options对象是各种参数配置// imemediatedeep和vue2中的watch里的参数一样// detached默认是false正常情况下当订阅所在的组件被卸载时订阅失败// 当值为true时即便订阅的组件被卸载订阅依然生效},{imemediate:false,deep:false,detached:false})// 停止订阅监听subscribeName();七、监听Actions $onAction() const subActiondemoStore.$onAction((name,store,args,after,onError){// name: actions的名字// store: store实例// args: 调用这个actions用的参数// after((result){// // 在action执行完毕后执行的逻辑// })// onError((result){// // 在action执行异常后执行的逻辑// })},true)// true组件卸载后监听依旧保留// 停止监听ActionssubAction();Tip可以在pinia实例上使用watch()函数侦听整个state。 watch(pinia.state,(state){// 每当状态发生变化时将整个state持久化到本地存储localStorage.setItem(,JSON.stringify(state))},}{deep:true})Tip不使用setup时。 import { mapState, mapActions } from pinia;import { mainStore } from /store/index.tsexport default {computed:{...mapState(mainStore,[name,count,getName]),// 定义myOwnName:name},// 可以在组件中通过this.name访问methods:{...mapActions(mainStore,[updateName]),d// 定义myOwnName:updateName},// 可以在组件中通过this.updateName()调用}}