10、vuex应用程序状态管理

167 阅读3分钟

一vueX的概念:

1、vuex采用集中式存储管理应用的所有组件的状态。

2、vuex在这个应用中只有一个实例存在。

3、仓库的数据是响应式的。

-   **状态**,驱动应用的数据源;
-   **视图**,以声明方式将**状态**映射到视图;
-   **操作**,响应在**视图**上的用户输入导致的状态变化。

3-1  提交 **mutation** 是更改状态的唯一方法,并且这个过程是同步的。
3-2  异步逻辑都应该封装到 **action** 里面。

二、vuex解决的问题

1、保证单向数据流原则。

2、实现组件多层嵌套数据共享。

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
	  count:0
  },
  mutations: {
	  add(state){
		   console.log(arguments);
		  state.count++
	  }
  },
  actions: {
	  syncAdd(){
		  console.log(arguments);
	  }
  },
  modules: {
  }
})
import * as vuex from 'vuex'

console.log(vuex);

image.png

三、State

1、在组件中通过$store.state.xxx获取数据

2、通过计算属性保存数据到当前组件实例:

<p>仓库状态:{{count}}</p>

computed:{
	count(){
		return this.$store.state.count;
	}
}

3、mapState辅组函数生成计算属性,返回一个对象,通过拓展运算符把每一个方法合并到计算属性的对象中:

2种使用方式:

//1、计算属性的名称与 state 的子节点名称相同时使用数组
 computed: {
 ...vuex.mapState(['count'])
 localCompute(){}
 }
 //2、使用对象的作为参数
 computed: {
	...vuex.mapState({
		localCount(state) {
			return state.count 
		}
	}),
	localCompute() {}
}
 

四、在 store 中定义“getter”

1、为了解决 store 中的 state 中派生出一些状态,就像组件中的computed一样;

2、getter对象里面的方法返回的结果,就像计算属性一样会被缓存起来;

3、getter对的方法接收2个参数:1、state对象、2、getter对象

image.png

4-1组件中的2种使用方式:

1、通过属性访问:

 this.$store.getters.doubleCount

2、通过方法访问:如果为了getter方法能够接受用户参数, 让getter对象的方法返回一个函数。

getByType(state, getters) {
	return function(type) {
		return state.arr.filter(item => {
			if (type === 'even') {
				return item % 2 === 0
			} else {
				item % 2 !== 0
			}
		})
	}
}

//在组件中通过方法传参数访问
this.$store.getters.getByType('even');

4-2:mapGetters 辅助函数

mapGetters函数把仓库中getter对象的方法映射到组件的compute对象中

mapGetters函数可以接受一个数组或者对象作为参数:

1、接受数组:

...vuex.mapGetters(['getByType']),

2、接受对象:给getter方法设置别名

 ...vuex.mapGetters({getByTypeAlias:'getByType'}),

五:mutation同步改变仓库中的状态:

mutations: {
	add(state, count) {
		console.log(arguments);
		state.count += count
	}
},

5-1、mutation对象中的方法接受2个参数:

1、第一个参数是state对象

2、第二个参数是用户参数(可选)

3、方法内部的arguments.length的长度永远都是2,这也意味着,如果需要传多个参数,只能通过对象来包装参数

5-2、在组件中改变仓库中的状态的2方法:

//以变量传参
this.$store.commit('add',1)
//以对象传参
 this.$store.commit({type:'add',count:2})

5-3:mapMutations 辅助函数将Mutations对象中的方法映射到组件的methods对象中:

 ...vuex.mapMutations(['add'])
 //和组件中方法的调用方式一样
 this.add(1)

六:actions异步改变仓库中的状态:

mutations: {
	add(state, arg) {
		console.log(arguments.length);
		state.count +=arg.count;
	}
},
actions: {
	syncAdd(context) {
		console.log(store===context);//false
		console.log(store.commit===context.commit);//true
		console.log(arguments.length===2);//true
		setTimeout(context.commit,0,{type:'add',count:2})
	}
},

image.png

6-1:actions对象中的方法接受2个参数

第1个参数:是包含指向与store 实例一部分相同方法和属性的对象。

第2个参数:是用户调用参数。

3、方法内部的arguments.length的长度永远都是2,这也意味着,如果需要传多个参数,只能通过对象来包装参数

6-2:组件中调用;

this.$store.dispatch('syncAdd',1);

6-3: mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用:

...vuex.mapActions(['syncAdd']),
...vuex.mapActions({syncAdd:'syncAdd'}),

6-4:由于actions对象的方法是处理异步操作:为了给调用放提供调用结果,处理函数返回的 Promise对像:

actions: {
	syncAdd(context) {
		return new Promise((resolve, reject) => {
			setTimeout(() => {
				resolve('succuss')
				context.commit({ type: 'add', count: 2 })
			}, 0)
		})
	}
},
//调用
this.$store.dispatch('syncAdd',1).then(res=>{
	console.log(res);
});

6-4:async/await


function getData() {
	return new Promise((resolve, reject) => {
		setTimeout(resolve, 1000, 3)
	})
}

actions: {
	async syncAdd(context) {
		var res = await getData()
		var dd = context.commit({ type: 'add', count: res })
		return 'succuss'+res
	}
},