pinia的初步了解

61 阅读3分钟

前段时间看见官网说vue2官网文档将会停止更新,这意味着vue3将会作为工作中的开发主流。在使用vue3中,vue3引入了ts,随之更改的配套有element ui更改为了element plus。开发了一段时间之后,发现vuex出现了一个新的替代者(pinia)。下面是我阅读文档顺便做的记录,仅供参考。

与vuex的区别

  • 更简单的规范,提供了一个Composition API风格的API
  • 与ts结合更具备可靠的类型推断
  • 使用上:(Pinia API 与 Vuex ≤4 有很大不同)
1) mutations不再存在
2)不再有 modules 的嵌套结构
3)没有 命名空间模块
4)可以直接对store中state数据进行赋值操作。

pinia的使用方法

  • 定义store
官网中提供defineStore()来定义,并且需要给予store一个唯一的名称

import { defineStore } from 'pinia'

// useStore 可以是 useUser、useCart 之类的任何东西
// 第一个参数是应用程序中 store 的唯一 id
export const useStore = defineStore('main', {
  // other options... 此处定义store的内容state,getters,actions
})

书写方法:由于pinia中已经没有modules的概念,编写的时候,根据实际需求,需要多少个store就写多少个store文件
  • state
1)对象定义格式(类似于vue2中data的定义方式)
//写法一
state: () => {
    return {
      counter: 0,
      name: 'Eduardo',
      isAdmin: true,
    }
  }
//写法2
state: () => ({
//内容
})
2)在组件中使用时,对state的访问及更改
//直接修改
storeName.counter++   或者  storeName.name="小王"

//$patch (正对于state的批量修改)
* 对象修改法
store.$patch({
  counter: store.counter + 1,
  name: 'Abalam',
})
注意:此处的store指的是引入文件时,store的命名
缺点:这种方式若只修改counter一个属性,但是却需要附带其余所有其他属性(不需要修改的),修改代价比较大

* 函数修改法(哪些需要修改就写哪些)
cartStore.$patch((state) => {
  state.items.push({ name: 'shoes', quantity: 1 })
  state.hasChanged = true
})

//整个state替换(运用场景较少)
store.$state = { counter: 666, name: 'Paimon' }

//state初始值重置功能
storeName.$reset()

  • getters
1.定义格式
 getters: {
    doubleCount: (state) => state.counter * 2,
  }
  
2.可以访问this
在定义中可用this访问到store实例
 doublePlusOne(): number {
      return this.counter * 2 + 1
    }
注意:
* 使用this时,不可以用箭头函数定义,箭头函数中使用this,this指向会变更
* 函数中this访问时,在ts文件中,必须明确返回类型

3.如何传递参数(返回函数)
getters如同computed计算属性,若想接收参数,可以返回一个函数
//定义
getters: {
    getUserById: (state) => {
      return (userId) => state.users.find((user) => user.id === userId)
    },
  }
//页面使用
storeName.getUserById(1) //传参
storeName.doubleCountPlusOne //无传参定义时的访问

  • actions
//类似于methods,主要用于业务逻辑的定义
//可以是同步,也可以是异步
actions: {
    increment() {
      this.counter++
    },
    randomizeCounter() {
      this.counter = Math.round(100 * Math.random())
    },
    //异步
    async registerUser(login, password) {
        this.userData = await api.post({ login, password })
      }
    },
  }

//页面调用
storeName.randomizeCounter()

特殊补充:

pinia中定义的state,实际就是使用vue3中reactive定义的一个对象,页面中访问的时候,若直接对它进行结构,会丧失响应式的功能,如下效果:

//以下作为错误示范(会造成响应式丢失)
let { count, price } = storeCounter;

效果:若store.count中途改变数值,此处的count不会随之改变

//解决办法:storeToRefs
let { count, price  } = storeToRefs(storeCounter); //为所有属性添加响应式refs
使用时:
 count.value来访问值