一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);
三、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对象
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})
}
},
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
}
},