一文学会大菠萝Pinia-看不懂给我一拳

1,188 阅读3分钟

Pinia安装和配置

介绍

Pinia是vue团队全新推出的最新款全局状态管理工具,八嘎,又他娘更新了。很明显这就是Vuex4的升级版Vuex5。小伙伴们顿时感觉既期待又桑心,期待的是这款数据存储工具是否更加灵活,轻巧,便捷。同时也吐槽知识更新太快,学不过来啊。

我自己也是试了水,感觉还不错。相比较Vux4,我个人感觉其优点还是十分明显

  • 对比Vuex4,pinia上手更容易,操作更简单
  • 对比Vuex4,极大的简化了模块化设计
  • 对比Vuex4,取消了mutations,使用actions代替同步和异步修改

下载

npm i pinia

项目初始化

store目录下创建index.js

其中defineStore的参数1是模块名,参数2是一个对象。

import {defineStore} from "pinia"
export const userStore = defineStore("user",{
  state:()=>{
    return {
      num:1
    }
  },                                              
  getters:{
    
  },
  actions:{
    
  }
})

main.js初始化pinia

import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
//1.创建pinia对象
const pinia = createPinia()
//2.全局挂载
createApp(App).use(pinia).mount('#app')

Pinia使用

state数据读取:读取应保证数据的响应式存在

方式一:直接读取

<template>
    <div>
        {{store.num}}
    </div>
</template>

<script lang="ts" setup>
  import { userStore } from '@/store/index.js';
  import {storeToRefs } from "pinia"
  const store = userStore()
</script>

页码显示 1

方式二:使用storeToRefs解构

<template>
   <div>
        {{num}}
    </div>
</template>

<script lang="ts" setup>
  import { userStore } from '@/store/index.js';
  import {storeToRefs } from "pinia"
  const store = userStore()
  //const {num} = store 直接结构是错误的,会让num数据失去响应式
  const {num} = storeToRefs(store)
</script>

getters:和Vuex4作用一样,只能读取state的数据,无法修改。类比computed,就是对state的数据进行一层修饰。并且当依赖的state数据不改变时,具有缓存的效果。

pinia数据

import {defineStore} from "pinia"
export const userStore = defineStore("user",{
  state:()=>{
    return {
      num:1
    }
  }, 
  //和vuex一样,只有一个参数state
  getters:{
    dealNum:function(state) {
      return state.num+1000
    }
  }
})

组件中使用getters:对比vuex4,pinia做了很大的优化,我们可以使用storeToRefs同时解构出state和getters的数据,十分便捷。

<template>
   <div>
        {{num}}
        {{dealNum}}
   </div>
</template>
<script lang="ts" setup>
  import { userStore } from '@/store/index.js';
  import {storeToRefs } from "pinia"
  const store = userStore()
  
  const {num,dealNum} = storeToRefs(store)
</script>

//页面显示 1和1001

actions

同步或者异步代码修改state数据

pinia数据

import {defineStore} from "pinia"
export const userStore = defineStore("user",{
  state:()=>{
    return {
      num:1
    }
  }, 
  //和vuex一样,只有一个参数state
  getters:{
    dealNum:function(state) {
      return state.num+1000
    }
  },
  //对比vuex,省略参数state。
  actions:{
  
    //同步代码修改
    addNum:function(payload) {
      this.num += payload
    }
    //异步代码修改
    addNumAsync:function(payload) {
        setTimeout(()=>{this.num += payload},2000)
    }
  }
})

组件中使用:pinia对于数据actions的修改做了很大优化,可以直接使用store.方法调用actions的方法

<template>
    <div>
        {{num}}
    </div>
    <div @click='change1'>同步修改num</div>
    <div @click='change2'>异步修改num</div>
</template>
<script lang="ts" setup>
  import { userStore } from '@/store/index.js';
  import {storeToRefs } from "pinia"
  const store = userStore()
  
  const {num} = storeToRefs(store)
  
  const change1 = ()=> {
      store.addNum(10)
  }
  const change2 = ()=> {
      store.addNumAsync(100)
  }
</script>

//页面显示 1,点击同步修改,页面显示11.点击异步修改,2s后页面显示101

修改数据其它方式

通过vuex我们知道数据修改只能通过mutaions和actions完成修改,但pinia增加了许多种数据修改的方式,并且保证了数据响应式。

方式一:直接通过 store.数据 进行修改

<template>
    <div>
        {{num}}
    </div>
    <div @click='change'>直接修改num</div>
   
</template>
<script lang="ts" setup>
  import { userStore } from '@/store/index.js';
  import {storeToRefs } from "pinia"
  const store = userStore()
  
  const {num} = storeToRefs(store)
  
  //直接通过store.num操作数据
  const change = ()=> {
      store.num++
  }
  
</script>

页面显示1,点击修改后,显示2

方式二:store.$patch修改,适用于批量修改数据,可有效减少页面二次渲染。

 <template>
    <div>
        {{num}}
    </div>
    <div @click='change'>直接修改num</div>
   
</template>
<script lang="ts" setup>
  import { userStore } from '@/store/index.js';
  import {storeToRefs } from "pinia"
  const store = userStore()
  
  const {num} = storeToRefs(store)
  
  const change = ()=> {
      store.$patch(state=>{
          state.num++
      })
  }
  
</script>

页面显示1,点击修改后,显示2

模块化

pinia的模块化对比vuex4简直是大优化,直接省略了许多。如果您对vuex4的模块化不清楚,可以看我的上一篇文章

看完这篇,还不会vuex.你给我一拳

pinia在使用defineStore定义数据时,第一个参数就指定了当前模块。在组件中,我们需要使用哪个模块直接导入这个模块的文件就可以直接使用。

结语

如果我的文章对你有帮助,希望你高抬贵手,点个赞再走也不迟,你的支持就是我的最大动力。如果感觉有问题,欢迎线上给我一拳。