Vuex
- 主要应用于Vue.js中管理数据状态的一个库
- 通过创建一个集中的数据存储,供程序中所有组件访问
使用场景
- 涉及到非父子关系的组件,例如兄弟关系、祖孙关系,甚至更远的关系组件之间的联系
- 中大型单页应用,考虑如何更好地在组件外部管理状态
状态管理:
对于大型应用程序,有效地管理状态是至关重要的。Vuex是Vue.js的官方状态管理库,它提供了集中式的状态管理机制。通过学习Vuex的核心概念(state、mutations、actions、getters),你可以更好地组织和管理应用程序的状态。
核心概念:
State(状态):Vuex 使用单一状态树,即在一个对象中包含了全部应用层级的状态,这样可以方便进行状态的管理和维护。State 是存储数据的地方。
Getters(获取器):Getters 可以被看作是 store 的计算属性。你可以在 getter 中计算状态,这样可以在多个组件中复用计算逻辑。
Mutations(变更):Mutation 是唯一能够改变状态的方法。每个 mutation 都有一个字符串类型的事件类型和一个回调函数,该回调函数就是实际进行状态更改的地方。
Actions(动作):Actions 是用来提交 mutation 的方法。而不是直接变更状态,而是通过提交 mutation 的方式来变更状态。可以在 action 内部进行异步操作。
Modules(模块):当应用变得非常复杂时,store 对象会变得非常庞大。Vuex 允许我们将 store 分割成模块(modules),每个模块拥有自己的 state、getters、mutations 和 actions。
1.基本使用:
// 引入vue
import Vue from 'vue'
// 引入vuex
import Vuex from 'vuex'
// 应用vue插件
//放这应该要在store前
Vue.use(Vuex)
// actions响应组件中的动作
const actions = {
}
// mutations操作数据state
const mutations = {
}
// 准备state存储数据
const state = {//状态对象
}
// 创建store并导出
const store = new Vuex.Store({actions,mutations,state,
})
//默认导出store
export default store
2.具体应用(选项式)
this.$store.commit('JIA',this.n)//直接走Mutation
this.$store.dispatch('jiaOdd',this.n)//走Action
//该文件用于创建Vuex中最为核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
//准备actions——用于响应组件中的动作
const actions = {
/* jia(context,value){
console.log('actions中的jia被调用了')
context.commit('JIA',value)
},
jian(context,value){
console.log('actions中的jian被调用了')
context.commit('JIAN',value)
}, */
jiaOdd(context,value){
console.log('actions中的jiaOdd被调用了')
if(context.state.sum % 2){
context.commit('JIA',value)
}
},
jiaWait(context,value){
console.log('actions中的jiaWait被调用了')
setTimeout(()=>{
context.commit('JIA',value)
},500)
}
}
//准备mutations——用于操作数据(state)
const mutations = {
JIA(state,value){
console.log('mutations中的JIA被调用了')
state.sum += value
},
JIAN(state,value){
console.log('mutations中的JIAN被调用了')
state.sum -= value
}
}
//准备state——用于存储数据
const state = {
sum:0 //当前的和
}
//创建并暴露store
export default new Vuex.Store({
actions,
mutations,
state,
})
3.Vuex其他配置:
getters(将state中的数据进行加工)
//所需原始数据*/,计算属性
//准备getters——用于将state中的数据进行加工
const getters = {
bigSum(state){return state.sum*10}
}
//取
this.$store.getters.bigSum
对象运算符
...
展开运算符(spread operator)允许一个表达式在某处展开。展开运算符在多个参数(用于函数调用)或多个元素(用于数组字面量)或者多个变量(用于解构赋值)的地方可以使用。展开运算符不能用在对象当中,因为目前展开运算符只能在可遍历对象(iterables)可用。iterables的实现是依靠[Symbol.iterator]函数,而目前只有Array,Set,String内置[Symbol.iterator]方法,而Object尚未内置该方法,因此无法使用展开运算符。
mapState(读取State中数据)
//借助mapState生成计算属性,从state中读取数据。(数组写法)
...mapState(['sum','school','subject']),
//借助mapState生成计算属性,从state中读取数据。(对象写法)
// ...mapState({he:'sum',xuexiao:'school',xueke:'subject'}),
mapGetters(读取getter中数据)
//借助mapGetters生成计算属性,从getters中读取数据。(数组写法)
...mapGetters(['bigSum'])
//借助mapGetters生成计算属性,从getters中读取数据。(对象写法)
// ...mapGetters({bigSum:'bigSum'})
mapMutations
//借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)...mapMutations({increment:'JIA',decrement:'JIAN'}),
//借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(数组写法)
// ...mapMutations(['JIA','JIAN']),
mapActions
//借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
//借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(数组写法)// ...mapActions(['jiaOdd','jiaWait'])
Tip:mapActions与mapMutations使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象。(MapActions与MapMutations传参)
4.Modules
使用单一状态树,导致应用的所有状态集中到一个很大的对象。但是,当应用变得很大时,store 对象会变得臃肿不堪。
为了解决以上问题,Vuex 允许我们将 store 分割到模块(module)。每个模块拥有自己的 state、mutation、action、getters、甚至是嵌套子模块——从上至下进行类似的分割:
const moduleA = {state: { ... },mutations: { ... },actions: { ... },getters: { ... } }const moduleB = {state: { ... },mutations: { ... },actions: { ... } }const store = new Vuex.Store({modules: {a: moduleA,b: moduleB} })store.state.a // -> moduleA 的状态 store.state.b // -> moduleB 的状态
模块的局部状态
对于模块内部的
mutation
和getter
,接收的第一个参数是模块的局部状态,对于模块内部的 getter,根节点状态会作为第三个参数:const moduleA = {state: { count: 0 },mutations: {increment (state) {// state 模块的局部状态state.count++}},getters: {doubleCount (state) {return state.count * 2},sumWithRootCount (state, getters, rootState) {return state.count + rootState.count}}
模块内部的 action,
context.state
是局部状态,根节点的状态是context.rootState
:const moduleA = {// ...actions: {incrementIfOddOnRootSum (context) {if ((context.state.count + context.rootState.count) % 2 === 1) {commit('increment')}}} }
5.VueX 高级
组合式API写法
组合式API:http://t.csdnimg.cn/WWEmT
组合式API与Vuex
可以通过调用
useStore
函数,来在setup
钩子函数中访问 store。这与在组件中使用选项式 API 访问this.$store
是等效的。import { useStore } from 'vuex'export default {setup () {const store = useStore()} }
为了访问 state 和 getter,需要创建
computed
引用以保留响应性,这与在选项式 API 中创建计算属性等效。import { computed } from 'vue' import { useStore } from 'vuex'export default {setup () {const store = useStore()return {// 在 computed 函数中访问 statecount: computed(() => store.state.count),// 在 computed 函数中访问 getterdouble: computed(() => store.getters.double)}} }
要使用 mutation 和 action 时,只需要在
setup
钩子函数中调用commit
和dispatch
函数import { useStore } from 'vuex'export default {setup () {const store = useStore()return {// 使用 mutationincrement: () => store.commit('increment'),// 使用 actionasyncIncrement: () => store.dispatch('asyncIncrement')}} }
插件与Vuex
Vue插件推荐博客:http://t.csdnimg.cn/ohptY
(待完善)