vuex
什么是VueX?
Vuex是一个专门为Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
状态管理到底是什么呢?我们可以简单的将其看成:把需要多个组件共享的变量全部存储在一个对象里面,然后将这个对象放在顶层的Vue实例中,让其他组件可以使用。
那么,有什么状态是需要我们在多个组件见共享的呢?
1. 比如用户的登录状态、用户名称、头像、地理位置信息等等
2. 比如商品的收藏、购物车中的物品等等
3. 这些状态信息,我们都可以放在统一的地方,对它进行保存和管理,而且它们还是响应式的。
Mutations 状态更新
Vuex的store状态的唯一更新方式:提交Mutation
Mutation主要包括两部分
1、字符串的事件类型(type)
2、一个回调函数(handler),该回调函数的第一个参数就是state
mutation的定义方式
mutations:{
increment(state){
state.counter++;
}
}
通过methods更新
(风格一 普通的提交风格)
increment(){
this.$store.commit('increment')
}
(风格一带参数)
addCount(count){
this.$store.commit('incrementCounter',count)
}
(特殊的提交风格)
addCount(count){
// 普通的提交风格
// this.$store.commit('incrementCounter',count)
// 特殊的提交风格
this.$store.commit({
type:'incrementCounter',
count //es6语法
})
}
在mutations里
incrementCounter(state, payload) {
// payload负载
// state.counter += count;
// console.log(count);
state.counter += payload.count;
}
Mutations响应规则
vuex的store中的state是响应式的,当state中的数据发生改变时,Vue组件就会自动更新。
这就要求我们遵守一些Vuex对应的规则
提前在store中初始化好所需的属性
当给state中的对象添加新的属性时,使用下面的方式。(info为state中的一个对象)
UpdateInfo(state) {
// 响应式的
state.info.name = 'xz';
// 第一种方式
Vue.set(state.info, 'address', '重庆');
Vue.delete(state.info, 'age');
// 第二种方式
state.info = {...state.info, 'height': 183.6 };
// 非响应式
state.info['address'] = 'xz';
delete state.info.age;
}
Mutations的类型常量
Mutations同步函数
- 通常情况下,Vuex要求我们Mutations中的方法必须是同步方法。
- 主要的原因是当我们使用devtools时,devtools可以帮助我们捕捉mutation的快照。
- 但是如果是异步操作,那么devtools将不能很好的追踪这个操作什么时候会被完成。
Actions的基本定义
- 强调,不要在Mutations中进行异步操作
- 但是某些情况,我们确实希望在Vuex中进行一些异步操作,比如网络请求,必然是异步的,这个时候怎么处理呢?
- Actions类似于Mutations,可以用来代替Mutations进行异步操作。
methods: {
updateInfo(){
// 提交到mutation中进行同步操作
// this.$store.commit('UpdateInfo')
// 提交到action中进行异步操作
// 没有参数
// this.$store.dispatch('aUpdateInfo')
// 有参数 参数可以是对象
this.$store.dispatch('aUpdateInfo',{
message:"我是携带信息",
})
// 因为函数返回的是promise所以then可以在这里操作
.then(()=>{
console.log('操作已经完成啦');
})
}
},
index.js文件里
actions: {
// context:上下文
// 没有参数
// aUpdateInfo(context) {
// setTimeout(() => {
// console.log(context);
// // 最终修改state一定要经过mutation,所以commit到mutation中再进行数据更新
// context.commit('UpdateInfo');
// // 有参数
// }, 1000)
// }
// 某些时候想通知,操作已经完成了
aUpdateInfo(context, payload) {
setTimeout(() => {
context.commit('UpdateInfo');
console.log(payload);
console.log(payload.message);
payload.success();
}, 1000)
}
// 上面这种方法不够优雅,所以使用promise
aUpdateInfo(context, payload) {
// 这个函数整体返回了一个promise
return new Promise((resolve, reject) => {
setTimeout(() => {
context.commit('UpdateInfo');
console.log(payload.message);
resolve('hhhhh');
}, 1000)
})
}
},
actions的另外一种写法
(原理)es6语法------对象的解构
const obj = {
name: 'csy',
age: 21,
height: 164
};
const { name, age, height } = obj;
console.log(name);
console.log(age);
console.log(height);
modules使用详解
- modules是模块的意思,为什么要在vuex中使用modules呢?
- Vuex使用单一状态树,那么也意味着很多状态都会交给Vuex管理,当应用变得非常复杂时,store对象就有可能变得相当臃肿
- 为了解决这个问题,Vuex允许我吗将store分割成模块(modules),而每个模块拥有自己的state,mutations,actions,getters
const ModuleA = {
state: {
name: 'csy'
},
mutations: {
// 同步修改数据
updateName(state) {
state.name = 'xz';
}
},
actions: {
// 异步修改数据
AUpdateName(context) {
setTimeout(() => {
context.commit('updateName');
}, 1000)
}
},
getters: {
// 类似于computed属性
// rootState是根部中的state
str(state, getters, rootState) {
return state.name + '123456' + rootState.info.name + getters.str1;
},
str1(state) {
return state.name + '今天天气真不错';
}
}
};
const store = new Vuex.Store({
modules: {
a: ModuleA
}
}