Vue Pinia 基础

 Vue Pinia 是一个专为Vue设计的状态管理库。它提供了一种简单、直观且强大的方式来管理Vue应用中的状态。

Store

用于保存和管理应用的状态。每个store都是一个独立的状态,包含自己的State、Getters和Actions。

State

状态,类似Vue的data。用于存储store的当前状态。

Getters

类似Vue的计算属性。

Actions

类似Vue的methods。

表 Pinia 的核心概念

// store/user.ts 选项式
import {defineStore} from "pinia";

export const useUserStore = defineStore('user',{
    state() {
        return {name: '',address: ''}
    },
    getters: {
        userStr: (state) => state.name + "/" + state.address
    },
    actions: {
        setInfo(name: string, address: string) {
            this.name = name
            this.address = address
        }
    }
})

// store/goods.ts 组合式
import { defineStore } from "pinia";
import {computed, ref} from "vue";

export const useGoodsStore = defineStore('goods',() => {
    const goods = ref({name: '', price: 0})
    const goodsStr = computed(() => goods.value.name + ":" + goods.value.price + "元")
    function updateGoodsInfo(name: string,price: number) {
        goods.value.name = name
        goods.value.price = price
    }
    return { goods, goodsStr, updateGoodsInfo }
})

1 Pinia基础

store 是一个用reactive包装的对象,不能对它进行解构,否则属性会失去响应性。可以使用storeToRefs()函数包装store,然后再进行解构,这样属性就仍具有响应性:

const userStore = useUserStore()
// const { name } = userStore // name不具有响应性
const { name } = storeToRefs(userStore) // name 具有响应性

1.1 State

使用选项式API时,可以通过调用store的$reset()方法将state重置为初始值。(在$reset()内部,会调用state()函数来创建一个新的状态对象,并用它替换当前状态。)

如果使用组合式API,需要在定义state时,创建自己的$reset()方法。

export const useGoodsStore = defineStore('goods',() => {
    // 省略其他代码
    function $reset() {
        goods.value = {name: '', price: 0}
    }
    return { goods, goodsStr,$reset, updateGoodsInfo }
})

变更state,可以调用$patch方法,该方法接收一个对象,用于替换当前的state。也接受一个函数(参数为state),来修改state的值。

function patchUpdate() {
  // 直接传入一个对象
   userStore.$patch({
     name: '刘女士',
     address: '东莞'
   })
  // 或者传入一个函数
  goodsStore.$patch((state) => {
    state.goods.name = '蓝莓'
    state.goods.price = 7
  })
}

1.1.1 订阅State

可以通过store的$subscribe()方法侦听state及其变化。比起普通的watch(),它的好处是subscriptions在patch后只触发一次。

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

1.2 Actions

可以通过store.$onAction()来监听action和它们的结果。传递给它的回调函数会在action本身之前前执行。参数是包含store、after及onError等属性的对象。after表示允许你在action解决后执行一个回调函数,OnError允许你在action抛出错误或reject时执行一个回调函数。

goodsStore.$onAction((
    {
      name, // action 名称
      store, // store 实例,类似 `goodsStore`
      args, // 传递给 action 的参数数组
      after, // 在 action 返回或解决后的钩子
      onError, // action 抛出或拒绝的钩子
    }) => {
    console.log('$onAction,action执行前执行',name,store,args)
    after((res) => {
       console.log('action执行完后再执行:',res)
    })
    onError((err) => {
       console.log("action报错时执行",err)
    })
})

1.3 插件

是一个函数,通过pinia.use()这个函数传递给pinia。插件接收一个可选参数context。该参数是一个包含app、pinia、store等实例的对象。

  1. 如果这个函数有返回值,返回值为一个对象,则该对象的所有属性都会被添加到每个store上。
  2. 每创建一个store实例,这个插件函数都会执行一遍。
pinia.use((context) => {
    console.log('pinia插件',context)
    return {
        type: context.store.$id + 'Plugin'
    }
})

1.3.1 添加新的state

必须同时在两个地方添加这个属性。

  1. 在store上,这样才可以用store.att 访问它。
  2. 在store.$state 上,然后才可以在devtools中使用它,并且在SSR时被正确序列化。
pinia.use((context) => {
    if (!context.store.$state.hasOwnProperty('other')) {
        context.store.$state.other = ref('')
    }
    context.store.other = toRef(context.store.$state, 'other')
    context.store.other = '其他信息'
    // 省略其他代码   
})

1.3.2 重置插件中添加的state

默认情况下,$reset()不会重置插件添加的state,但是可以重写它来重置添加的state。

pinia.use((context) => {
    // 省略其他代码
    const originalReset = context.store.$reset.bind(context.store)
    return {
        // 省略其他代码
        $reset() {
            originalReset()
            context.store.other = ''
        }
    }
})

1.3.3 TypeScript与插件

1)标注插件类型

function customPiniaPlugin(context:PiniaPluginContext) {
    // 省略其他代码
}
pinia.use(customPiniaPlugin)

2)为新的store属性添加类型

declare module 'pinia' {
    export interface PiniaCustomProperties {
        customInfo: string
    }
}

function customPiniaPlugin({ store }:PiniaPluginContext) {
    store.customInfo = 'hello'
}

3)为新的state添加类型。

declare module 'pinia' {
    export interface PiniaCustomStateProperties<S> {
        hello: string
    }
}

pinia.use(({ store }) => {
    store.$state.hello = '12'
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值