pinia从青铜到王者, 青铜篇

993 阅读1分钟

pinia

全局状态管理工具,可爱的小菠萝

Pinia.js 有如下特点:

完整的 ts 的支持;

  • 足够轻量,压缩后的体积只有1kb左右;
  • 去除 mutations,只有 state,getters,actions;
  • actions 支持同步和异步;
  • 代码扁平化没有模块嵌套,只有 store 的概念,store 之间可以自由使用,每一个store都是独立的
  • 无需手动添加 store,store 一旦创建便会自动添加;
  • 支持Vue3 和 Vue2

官网:pinia.vuejs.org/

新手指引

安装:yarn add pinia, npm i pinia

在main.js 中

 import {createApp} from 'vue'
 import App from './App.vue'
 ​
 import { createPinia } from "pinia";
 const pinia = createPinia()
 ​
 const app = createApp(App)
 app.use(router).use(pinia)
 app.mount('#app')

新建stroe文件夹,index.js

 import { defineStore } from "pinia";
 export const useUserStore = defineStore('user',{
   state:()=>{
     return{
       name:'ziheng',
       age:46
     }
   },
   getters:{},
   actions:{}
 })

在vue页面中,本文使用vue3组合式函数。

 <script setup>
  import { useUserStore } from "@/store";
  const UserStore = useUserStore()
 </script>
 ​
 <template>
   <h1>{{UserStore.name}}现在已经有{{UserStore.age}}了</h1>
 </template>

击杀红buff: 修改store中的值

有五种方式修改store中的值。

 <template>
   <div class="home">
     home
   </div>
   <h1>{{UserStore.name}}现在已经有{{UserStore.age}}了</h1>
   <div class="btn" @click="chageUserStore">改变</div>
 </template>
 <script setup>
  import { useUserStore } from "@/store";
  const UserStore = useUserStore()
  function chageUserStore(){
     //直接修改
     UserStore.age++     
     //批量...
  }
 </script>
 //直接修改
 UserStore.age++
 //批量修改
 UserStore.$patch({
     name:'xigua',
     age:18
 })
 //使用函数批量修改
 UserStore.$patch((state)=>{
     state.name='狗蛋',
     state.age=10
 })
 //替换原始对象
 UserStore.$state = {
     name:'p桃儿',
     age:3
  }
 //通过actions修改
 import { defineStore } from "pinia";
 ​
 export const useUserStore = defineStore('user',{
   state:()=>{
     return{
        //相当于data
       name:'ziheng',
       age:46
     }
   },
   getters:{
       //相当于计算属性
   },
   actions:{
      //相当于vue2中的methods
     userStorechange(name){
       this.name=name
     }
   }
 })
 //在vue页面
 UserStore.userStorechange('op')

击杀蓝buff : 解构store

 <template>
   <h1>{{UserStore.name}}现在已经有{{UserStore.age}}岁了</h1>
   <h1>{{name}}现在已经有{{age}}岁了</h1>
   <div class="btn" @click="chageUserStore">改变</div>
 </template>
 ​
 <script setup>
  import { ref, reactive, onMounted, onBeforeMount } from "vue";
  import { useUserStore } from "@/store";
  const UserStore = useUserStore()
  let {name, age} = UserStore  
  function chageUserStore(){
      UserStore.age++
  }
 </script>
 <style>
   .btn{
     background-color: aqua;
     width: 150px;
     height: 40px;
     line-height: 40px;
     position: relative;
     left: 50%;
     transform: translate(-50%);
   }
 </style>

image-20220929145849150.png

可以发现解构出来的值不是响应数据,这里和reactive一样,pinia提供了storeToRefs方法。

使用storeToRefs方法将store数据解构可以实现响应式

  import { storeToRefs } from "pinia";
  let {name, age} = storeToRefs(UserStore)
  function chageUserStore(){
     age++
  }

image-20220929150514380.png

协助队友击杀暴君: actions和getters

actions相当于vue2中的methods,在pinia中,actions可以做同步操作,也可以做异步操作,不再像vuex那么麻烦。

 import { defineStore } from "pinia";
 ​
 const login = ()=>{
   return new Promise(resolve=>{
     setTimeout(() => {
       resolve({
         name:'xigua',
         age:18
       })
     }, 3000);
   })
 }
 ​
 export const useUserStore = defineStore('user',{
   state:()=>{
     return{
       user:{},
       description:'子恒吃西瓜',
       computed:1
     }
   },
   getters:{
     newcomputed: (state)=>{
       return state.user.name
     }
   },
   actions:{
     async userStorechange(name){
       let user = await login()
       this.user = user
       this.desyibuafterChange()
     },
     desChange(){
       this.description = '现在是同步的描述'
     },
     desyibuafterChange(){
       this.description = '异步结束了,我再执行一次'
     }
   }
 })
 <template>
   <div class="wrap">
     <li>actions.同步 : {{description}}</li>
     <li>actions.异步 : {{user.name}}如今{{user.age}}了</li>
     <li>getters {{userStore.newcomputed}}</li>
   </div>
   <div class="btn" @click="chageUserStore">改变</div>
 </template>
 ​
 <script setup>
   import { storeToRefs } from "pinia";
   import { useUserStore } from "@/store";
   const userStore = useUserStore()
   let {user, description, computed} = storeToRefs(userStore)
   function chageUserStore (){
     userStore.userStorechange()
     userStore.desChange()
   }
 </script>
 <style>
   li{
     list-style: none;
     margin: 10px 0;
   }
   .btn{
     background-color: aqua;
     width: 150px;
     height: 40px;
     line-height: 40px;
     position: relative;
     left: 50%;
     transform: translate(-50%);
   }
 </style>

pinia.gif

进攻敌方防御塔: api篇

  • $reset

    用来恢复store初始状态

  • $abscribe

    只要state中的值发生变化就会执行这个函数

     userStore.$subscribe((args,state)=>{
       console.log(args,state)
     })
    

image-20220929171844763.png

第二个参数

如果你的组件卸载之后还想继续调用请设置第二个参数

```
 Test.$subscribe((args,state)=>{
    console.log(args,state);
    
 },{
   detached:true
 })
```
  • $onaction

    只要调用actions中的方法就会走这个函数

     userStore.$onAction((args)=>{
       console.log(args)
     },)
    

image-20220929171953594.png

after: 此方法中写的代码在onaction方法内的代码执行完后执行

onError:处理错误 异步

游戏胜利:victory,让我们共同庆祝,我们青铜一满星了

\