Vuex和Pinia的一些区别
- pinia支持组合式api
- pinia更好的支持TS
- pinia没有了mutation,pinia的action可直接修改state。
- pinia无需再使用dispatch分发action,也不需要使用commit提交mutation,可直接调用action。
- vuex只能创建一个store实例, pinia可以创建任意个。
- pinia没有了modules,可直接创建一个新的store作为module。vuex是一个对象嵌套的方式存储状态, 而pinia是
Vuex
vuex 3.x
通过Vuex.Store()
创建一个store;
Vuex.Store()
接受一个对象作为参数;
- 参数对象上的
key
值只能是state
、getters
、mutations
、actions
、modules
state
上定义的是共享的状态/变量
getters
上定义的是根据state派生出的状态
mutation
上定义的是可以同步修改状态的方法
actions
上定义的是可以异步/同步执行mutaions上的方法的方法
modules
上定义的是模块,可以根据业务将状态分模块存放,一个模块就是一个对象,该对象上的key值也是state
、getters
、mutations
、actions
、modules
。modules
上可以继续嵌套modules
。
Vuex实践
js
复制代码
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
interface Object {
[key: string]: any
}
const womanModule = {
state: {
pregnant: false //是否怀孕
},
mutations: {
setPregnant(state : Object, value: boolean) {
state.pregnant = value
}
},
actions: {
setPregnant(context : Object, value : boolean) {
context.commit('setPregnant', value)
}
}
}
const personModule = {
state: {
id: 0,
name: '',
age: 0
},
mutations: {
setId(state: Object, id: number) {
state.id = id
},
setName(state: Object, name: string) {
state.name = name
},
setAge(state: Object, age: number) {
state.age = age
}
},
actions: {
setId(context: Object, id: number) {
context.commit('setId', id)
},
setName(context: Object, name: string) {
context.commit('setName', name)
},
setAge(context: Object, age: number) {
context.commit('setAge', age)
}
},
modules: {
womanModule
}
}
export default new Vuex.Store({
state: {
},
getters: {},
mutations: {
},
actions: {
},
modules: {
personModule
}
})
使用store
js
复制代码
<template>
<div>
<div>{{ personModule.id }}</div>
<div>{{ personModule.name }}</div>
<div>{{ personModule.age }}</div>
<div>{{ personModule?.womanModule?.pregnant }}</div>
</div>
</template>
<script setup lang="ts">
import store from '../store/index'
const state : {[key: string]: any} = store.state;
const personModule : {[key: string]: any}= state.personModule;
store.dispatch('setId', 1)
store.dispatch('setName', 'role')
store.dispatch('setAge', personModule.age || 18)
store.dispatch('setPregnant', true)
</script>
Pinia实践
定义store
js
复制代码
import { ref, computed } from 'vue'
import type {Ref} from 'vue'
import { defineStore } from 'pinia'
// 选项式定义一个store
export const useTestPerson = defineStore('person', {
state: () => ({
id: 0,
name: '',
age: 0
}),
getters: {
adult() : boolean {
return this.age >= 18
}
},
actions: {
setId(value: number) {
this.id = value
},
setName(value: string) {
this.name = value
},
setAge(value: number) {
this.age = value
}
}
})
// 组合式定义一个store
export const useWoman = defineStore('woman', () => {
let pregnant: Ref<boolean> = ref(false)
const changePregnant = () => {
pregnant.value = !pregnant.value
}
return {
pregnant,
changePregnant
}
})
使用store
js
复制代码
<template>
<div>
<div>编号:{{ person.id }}</div>
<div>名称:{{ person.name }}</div>
<div>年龄:{{ person.age }}<el-button @click="changeAge">change age</el-button></div>
<div>是否成年:{{ person.adult }}</div>
</div>
<div>
<div>是否生育: {{ woman.pregnant }}<el-button @click="changePregnant">change</el-button> </div>
</div>
</template>
script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue'
import type {Ref} from 'vue'
import { ElButton, ElInput } from 'element-plus'
import { useTestPerson, useWoman } from '../stores/test'
//
const person = useTestPerson()
person.setId(1)
person.setName('lily')
person.setAge(18)
const changeAge = () => {
person.setAge(11)
}
//
const woman = useWoman();
const changePregnant = () => {
woman.changePregnant()
}
</script>