状态定义
const store = new Vuex.Store({
state: {
count: 0
}
})
- 通常会把不同模块的状态进行模块化拆分,每个模块也有自己的
state
。
- Pinia:使用
defineStore
函数定义一个store,其状态通过返回的对象定义。例如:
import { defineStore } from 'pinia'
const useCounterStore = defineStore('counter', {
state: () => ({
count: 0
})
})
- 写法更加简洁直观,并且在TypeScript支持上更好,无需额外的类型声明。
数据获取
- Vuex:通过
mapState
辅助函数或者直接从$store.state
获取。例如在组件中:
<template>
<div>{{ count }}</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
computed: {
...mapState(['count'])
}
}
</script>
- Pinia:在组件中直接使用
useStore
函数获取store实例,进而访问状态。例如:
<template>
<div>{{ counterStore.count }}</div>
</template>
<script>
import { useCounterStore } from '@/stores/counter'
export default {
setup() {
const counterStore = useCounterStore()
return {
counterStore
}
}
}
</script>
- Pinia的方式更符合组合式API的风格,更加灵活和直观。
Mutations使用
- Vuex:
mutations
是唯一能直接修改state
的方法,并且必须是同步操作。例如:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++
}
}
})
// 调用mutation
store.commit('increment')
- 这种严格的模式便于追踪状态变化,调试方便。
- Pinia:没有
mutations
概念,直接在store中定义修改状态的函数。例如:
const useCounterStore = defineStore('counter', {
state: () => ({
count: 0
}),
actions: {
increment() {
this.count++
}
}
})
// 调用修改函数
const counterStore = useCounterStore()
counterStore.increment()
- Pinia这种方式简化了操作,无需像Vuex那样区分同步异步操作,但调试追踪状态变化相对没那么直观。
Actions使用
- Vuex:
actions
用于处理异步操作,通过commit
触发mutations
来修改state
。例如:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++
}
},
actions: {
asyncIncrement({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
})
// 调用action
store.dispatch('asyncIncrement')
- Pinia:
actions
同样可用于异步操作,直接在函数内修改状态。例如:
const useCounterStore = defineStore('counter', {
state: () => ({
count: 0
}),
actions: {
async asyncIncrement() {
setTimeout(() => {
this.count++
}, 1000)
}
}
})
// 调用action
const counterStore = useCounterStore()
counterStore.asyncIncrement()
- Pinia的
actions
更加灵活,不需要像Vuex那样通过commit
来间接修改状态。