姐夫带我解锁了 Pinia 技能卡槽

214 阅读3分钟

一、 Pinia 是 Vue 的存储库

简介

Pinia是一个专门为Vue3设计的状态管理库,它利用Vue3的响应式系统和组合API,提供了一种简单、直观和类型安全的方式来管理应用程序的状态。Pinia的设计思想是基于Vuex的架构,但相比之下更加轻量级、易于使用,并且支持TypeScript。通过Pinia,开发者可以方便地组织和共享各种状态,例如用户身份验证、路由、UI状态等.

它允许您跨组件/页面共享状态。 使用Pinia进行状态管理的好处:

  • dev-tools 支持

    • 跟踪动作、突变的时间线
    • Store 出现在使用它们的组件中
    • time travel 和 更容易的调试
  • 热模块更换

    • 在不重新加载页面的情况下修改您的 Store
    • 在开发时保持任何现有状
  • 插件:使用插件扩展 Pinia 功能

  • 为 JS 用户提供适当的 TypeScript 支持或 autocompletion

  • 服务器端渲染支持

安装

npm install pinia 
// yarn add pinia

二、基本代码风格

  1. 从pinia中导出定义仓库api,即defineStore.
  2. 新定义一个仓库,defineStore可以接受两个参数,第一个参数是非重复的仓库名称id,第二个参数可以接收一个对象,该对象存在三种函数方法,即stateactionsgetters.
  3. 将该 defineStore 定义为常量并使用export导出,通常格式为useXXX,例如useStore、useUser.
// stores/counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => {
    return { count: 0 }
  },
  // 也可以定义为
  // state: () => ({ count: 0 })
  actions: {
    increment() {
      this.count++
    },
  },
  getters:{
  }
})

上述代码定义了一个名为counter的状态,包含一个名为count的属性,和一个increment方法.

三、Pinia基础使用方法:

  1. 导入定义好的仓库并将实例传递给常量store.
  2. pinia本质使用reactive包裹数据,因此不需要使用.value进行取值
  3. Pinia不允许直接使用解构赋值!例如: const { name , age } = store 因为这样会丢失响应式.
  4. 如需在pinia中使用解构,可以使用storeToRefs ,该API可以维持解构之后的数据响应式,但必须是仅使用 store 中的状态但不调用任何操作可以使用.
import { useStore } from '@/stores/counter'

export default {
  setup() {
    const store = useStore()
    //解构
    const {name , age } = storeToRefs(store)
    
    return {
      // 您可以返回整个 store 实例以在模板中使用它
      store,
      name,
      age
    }
  },
}

四、state使用

  1. 从state中拿到数据
  • 当我们使用const Store = useStore() 后,可以直接通过Store.age来使用相应的属性值。
  • 我们可以也直接通过Store.age=? 来修改数据,例如Store.age++
  1. 批量修改state的值,使用$patch,例如:
    const Store = useStore();
    const change = () => {
        Store.$patch({
            age : 100,
            name: 'Asen'
        })
    }
    
    //亦可以使用函数形式
    
    const change = () => {
        Store.$patch((state)=>{
            state.age = 100;
            state.name  = 'Asen'
        }
    }
  1. 可以通过$state来直接覆盖Store中的state,但必须修改整个对象的全部属性
    const Store = useStore()
    const change = () =>{
        Store.$state = {
            name:'Asen',
            age:18
        }
    }
    

Action使用

Actions,就像组件中的methods,其中可以写一些自定义方法
同步操作的基本使用方法:

    import { defineStore } from 'pinia'
    export const useStore = defineStore('Test',{
       state:()=>({
           count: 0 
       }),
       actions:{
           add(){
               this.count++
           },
           clear() {
               this.count = 0;
           }
       }
    })
    
    //在组件中引入Store
    const Store  = useStore()
    
    const add = ()=>{
        Store.add() //直接调用actions中的方法
    }

异步操作的基本使用方法:

   Const Info = () => {
       return new Promise((resolve) =>{
           setTimeout(()=>{
               resolve({
                   age:18,
                   name:'Asen'
               })
           },5000)
       })
   }
export const useStore = defineStore('Test',{
    state:()=>({
        userInfo:{},
     })
     actions:{
         async getInfo() {
            //等待Login()执行结束之后进行
             const res = await Login()
             this.user = res
         }
     }
})

Author: Asen

2023/3/28