vue中新的状态管理器-pinia
背景
对于pinia的使用,可参考官方文档在这不做过多赘述。这边主要来讲讲pinia中 少用且好用的方法,为什么我们选择pinia而不用vuex
ps: 以下写法全部基于组合式API
使用方式:
先下载依赖
npm i pinia -s
在vue3中,main.js这么写
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
app.mount('#app')
ps:就别考虑v2了吧,v2老老实实用vuex。
State
1、如何修改State
在传统的vuex中我们是不建议直接修改state的,而是要求我们通过mutation来修改state,但是在pinia中我们可以直接修改state。例如:
const store = useStore()
store.count++
如果我们需要在同一时间变更多个属性,可以通过$patch方法,例如:
store.$patch((state) => {
state.items.push({ name: 'shoes', quantity: 1 })
state.hasChanged = true
})
2、如何订阅State
用来监听state是否发生变化,与watch相比,使用 $subscribe() 的好处是 subscriptions 在 patch 后只触发一次 。例如
cartStore.$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 // 传递给 cartStore.$patch() 的补丁对象。
// 每当状态发生变化时,将整个 state 持久化到本地存储。
localStorage.setItem('cart', JSON.stringify(state))
})
在组合式API中可以这么使用:
<script setup>
const someStore = useSomeStore()
// this subscription will be kept even after the component is unmounted
someStore.$subscribe(callback, { detached: true })
</script>
Getter
1、如何访问其他store 的 getter
想要使用另一个 store 的 getter 的话,那就直接在 getter 内使用就好,例如:
import { useOtherStore } from './other-store'
export const useStore = defineStore('main', {
state: () => ({
// ...
}),
getters: {
otherGetter(state) {
const otherStore = useOtherStore()
return state.localData + otherStore.data //otherStore.data 就是其他getter中的getter
},
},
})
2、如何像getter中传递参数
Getter 只是幕后的计算属性,所以不可以向它们传递任何参数。不过,你可以从 getter 返回一个函数,该函数可以接受任意参数,例如
export const useStore = defineStore('main', {
getters: {
getUserById: (state) => {
return (userId) => state.users.find((user) => user.id === userId)
},
},
})
组件中使用:
<script setup>
import { useUserListStore } from './store'
const userList = useUserListStore()
const { getUserById } = storeToRefs(userList)
// note you will have to use `getUserById.value` to access
// the function within the <script setup>
</script>
<template>
<p>User 2: {{ getUserById(2) }}</p>
</template>
ps: getter 将不再被缓存,它们只是一个被你调用的函数。不过,你可以在 getter 本身中缓存一些结果,虽然这种做法并不常见,但有证明表明它的性能会更好
Action
1、如何访问其他 store 的 action
举个