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
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实践
- 定义store
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
<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
- Pinia的 Store 是用
defineStore()
定义的,它的第一个参数要求是一个独一无二的名字 defineStore()
的第二个参数可接受两类值:Setup 函数或 Option 对象。
-
与 Vue 的选项式 API 类似,我们也可以传入一个带有
state
、actions
与getters
属性的 Option 对象 -
也存在另一种定义 store 的可用语法。与 Vue 组合式 API 的 setup 函数 相似,我们可以传入一个函数,该函数定义了一些响应式属性和方法,并且返回一个带有我们想暴露出去的属性和方法的对象。
在 Setup Store 中:`ref()` 就是 `state` 属性 `computed()` 就是 `getters` `function()` 就是 `actions`
Pinia实践
定义store
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
<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>
推荐
原文链接:https://juejin.cn/post/7347905312478969919 作者:yanessa_yu