vue3学习-Pinia状态管理

Pinia

定义一个Store

import {
    
     defineStore } from 'pinia'
export const useStore = defineStore('main', {
    
    })

这个 name,也称为 id,是必要的,Pinia 使用它来将 store 连接到 devtools。

将返回的函数命名为 use… 是跨可组合项的约定,以使其符合你的使用习惯。

使用 store

import {
    
     useStore } from '@/stores/counter'
const storeObj = useStore()
console.log(storeObj.count)

一旦 store 被实例化,你就可以直接在 store 上访问 stategettersactions 中定义的任何属性

store 是一个用reactive 包裹的对象,这意味着不需要在getter 之后写.value

就像setup 中的props 一样,我们不能对其进行解构

为了从 Store 中提取属性同时保持其响应式,您需要使用storeToRefs()

import {
    
     useStore } from '@/stores/counter'
const {
    
     count } = useStore()
console.log(count)//失去响应

#解决
import {
    
     storeToRefs } from 'pinia'
const {
    
     count }  = storeToRefs(useStore())
console.log(count.value)

state

在 Pinia 中,状态被定义为返回初始状态的函数。

const useStore = defineStore('main', {
    
    
    state: () => {
    
    
        return {
    
    count: 0}
})

访问“state”

const storeObj = useStore()
store.count++

重置状态

const storeObj = useStore()
storeObj.$reset()

改变状态

可以之恶杰修改: store.count++

可以调用 $patch 方法

storeObj.$patch({
    
    
    otherProp: 'main'//其他属性
    count: storeObj.count + 1
})

storeObj.$patch((state) => {
    
    
    state.item.push({
    
    name: 'RenNing', age: 18})
    state.count = ++state.count
})

$patch 方法也接受一个函数来批量修改集合内部分对象的情况

替换state

store.$state = {
    
     counter: 666, name: 'Paimon' } //{ counter: 666, name: 'Paimon' }
store.$state = {
    
    }

只针对原定义好的属性,未定义的数据虽然会添加上,但是不起作用

订阅状态

通过 store 的 $subscribe() 方法查看状态及其变化

与常规的 watch() 相比,使用 $subscribe() 的优点是 subscriptions 只会在 patches 之后触发一次

storeObj.$subscribe((mutation, state) => {
  // import { MutationType } from 'pinia'
  mutation.type // 'direct' | 'patch object' | 'patch function'
  // 与 cartStore.$id 相同
  mutation.storeId // 'cart'
  // 仅适用于 mutation.type === 'patch object'
  mutation.payload // 补丁对象传递给 to cartStore.$patch()

  // 每当它发生变化时,将整个状态持久化到本地存储
  localStorage.setItem('cart', JSON.stringify(state))
})

认情况下,state subscriptions 绑定到添加它们的组件

当组件被卸载时,它们将被自动删除

如果要在卸载组件后保留它们,请将 { detached: true } 作为第二个参数传递给 detach 当前组件的 state subscription

storeObj.$subscribe(callback, {
    
    detached: true})

您可以在 pinia 实例上查看整个状态:

watch(
  pinia.state,
  (state) => {
    // 每当它发生变化时,将整个状态持久化到本地存储
    localStorage.setItem('piniaState', JSON.stringify(state))
  },
  { deep: true }
)

getter

defineStore() 中的 getters 属性定义。

接收“状态”作为第一个参数以鼓励箭头函数的使用

export const useStore = defineStore('count', {
    
    
    state: () =>{
    
    {
    
    count: 1}},
    getters: {
    
    
        //方法一
        doubleCount: (state) => {
    
    return state.count * 2}//方法二
        doublePlusOne(): number {
    
     return this.counter * 2 + 1 },
    }
})

将参数传递给 getter

# 定义
getters: {
    
    
	getUserId(state) =>{
    
    
        const arr = state.foo.filter(....)
        return (userId) => arr.find(id => userId == id)
    }
}
#使用
{
    
    {
    
    getUserId(2)}}

执行此操作时,getter 不再缓存,它们只是您调用的函数。

但是,您可以在 getter 本身内部缓存一些结果

反问其他Store的getter

import {
    
    useOtherStore} from './other-sotre'
getters: {
    
    
    otherGetter(state) {
    
    
        const otherStore = useOtherStore()
        return state.localDate + otherStore.data
    }
}

没有setup()

import {
    
     mapState } from 'pinia'
computed:{
    
    
    ...mapState(useCounterStroe, ['doubleCount'])
}

Actions

相当于组件中的methods。适合定义业务逻辑

export const useStore = defineStore('main', {
    
    
    actions: {
    
    
        increment() {
    
    this.count++},
        async getApi() {
    
    
            try{
    
    
                let res = await post('url',options)
            }catch{
    
    
                
            }
        }
    },
    
})

getters 一样,操作可以通过 this 访问

actions 可以是异步的

调用

Actions 像 methods 一样被调用:

useStore.getApi()

不适用 setup()

可以使用 mapActions() 将操作属性映射为组件中的方法

import {
    
     mapActions } from 'pinia'
import {
    
     getApi } from '../stores/useStore.js'
methods:{
    
    
    ...mapActions(getApi)
}

订阅Actions

使用 store.$onAction() 订阅 action 及其结果

const unsubscribe = someStore.$onAction(
  ({
    
    
    name, // action 的名字
    store, // store 实例
    args, // 调用这个 action 的参数
    after, // 在这个 action 执行完毕之后,执行这个函数
    onError, // 在这个 action 抛出异常的时候,执行这个函数
  }) => {
    
    
    // 记录开始的时间变量
    const startTime = Date.now()
    // 这将在 `store` 上的操作执行之前触发
    console.log(`Start "${
      
      name}" with params [${
      
      args.join(', ')}].`)

    // 如果 action 成功并且完全运行后,after 将触发。
    // 它将等待任何返回的 promise
    after((result) => {
    
    
      console.log(
        `Finished "${
      
      name}" after ${
      
      
          Date.now() - startTime
        }ms.\nResult: ${
      
      result}.`
      )
    })

    // 如果 action 抛出或返回 Promise.reject ,onError 将触发
    onError((error) => {
    
    
      console.warn(
        `Failed "${
      
      name}" after ${
      
      Date.now() - startTime}ms.\nError: ${
      
      error}.`
      )
    })
  }
)

// 手动移除订阅
unsubscribe()

调用方法时/后触发

默认情况下,action subscriptions 绑定到添加它们的组件,默认情况下,action subscriptions 绑定到添加它们的组件。

如果要在卸载组件后保留它们,请将 true 作为第二个参数传递给当前组件的 detach action subscription

// 此订阅将在组件卸载后保留
someStore.$onAction(callback, true)

猜你喜欢

转载自blog.csdn.net/weixin_46211267/article/details/132148509