Pinia和Vuex都是Vue状态管理的库,但是它们在实现方式和使用方法上有所不同。
Vuex采用了全局单例模式,通过一个store对象来管理所有的状态,组件通过store对象来获取和修改状态。
Pinia则采用了分离模式,即每个组件都拥有自己的store实例,通过在组件中创建store实例来管理状态。
Vuex要求在组件中通过mapState、mapGetters等方法来获取状态或者通过dispatch和commit方法来修改状态,需要额外引入mapState等辅助函数。
Pinia则直接将状态挂载在组件实例上,通过createStore和useStore方法来创建和使用store实例,更加简洁和容易理解。
Vuex的源码相对较为复杂,涉及到了响应式系统的实现、状态变更的批处理等。
Pinia的源码相对较为简单,主要是通过Vue的provide/inject实现store实例的分发和共享。
Pinia的核心是Store
类,它继承自Vue的reactive
和readonly
方法,以及PiniaStore
接口。PiniaStore
接口定义了一些基本的方法,例如getState
、setState
、subscribe
、off
等,用于状态的读取、更新和订阅。
Store
类还使用了createApp
方法来创建一个Vue实例,在该实例的setup函数中将pinia
实例注入到app的provide中,这样就可以在其他组件中使用useStore()
来获取相应的store
实例。
Store
类还提供了一些常用的方法,例如useActions
和useState
,用于在组件中调用store
的方法或获取状态。这些方法内部都使用了Vue的inject
和provide
方法来实现数据的传递。
在整个库中,Store
类的源码是最为关键的部分,它使用了Vue 3的响应式系统来实现了状态的管理和更新。同时,它还提供了一些方便的API来处理常见的状态管理需求,例如模块化、订阅等。
//Vuex
import Vuex from 'vuex'
import Vue from 'vue'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++
}
}
})
// 组件中
import { mapState } from 'vuex'
export default {
computed: {
...mapState([
'count'
])
},
methods: {
increment() {
this.$store.commit('increment')
}
}
}
// Pinia
import { createPinia } from 'pinia'
import { defineComponent, ref } from 'vue'
const pinia = createPinia()
// 定义store
pinia.store('counter', {
state: () => ({
count: 0
}),
actions: {
increment() {
this.count++
}
}
})
// 组件中
export default defineComponent({
setup() {
const store = pinia.useStore('counter')
const count = ref(0)
return {
count,
increment() {
store.increment()
}
}
}
})