学过Vue的伙伴们都知道在简单的场景下,父子组件的通信可以用Props完成,孩子组件与父组件之间可以emit(触发)一个事件完成通信。但是在复杂的场景下,比如购物商城由于涉及到多组件通信(这里不单单是父子组件,还有兄弟组件)上面的方法就显得力不从心了。这时候就需要我们Vuex闪亮登场了。
分享个demo有兴趣的小伙伴可以去看看,对你有帮助记得给个Star哦,谢谢!
什么是Vuex?
官方说法:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
简单理解:就是保持相同的状态,何为保持相同的状态呢,看下图:
想必大家都不陌生,在购物商城中当你添加完商品后。头部或者是右边的购物车列表就会在不刷新页面的情况下同步更新添加的商品。假如这个购物车列表只要商品列表页中同步更新状态的话,那很简单我们就可以单纯的用父子间的通信去保持状态同步。但是实际场景中并不是如此,还会在购物车中,商品详情页等页面改变状态(不太理解的小伙伴去试试demo)。所以这时候就需要用到我们的Vuex。
安装
基本每种插件都有多种的安装方法,但是为了减少篇幅这里我们只说npm方式安装,想要了解更多安装方式,请移步。
npm安装方式:
安装方式:npm install vuex --save
使用:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
可以在main.js中安装也可以单独创建一个store在store中需要用到的地方安装,但是别忘了将store挂载到mian.js中。
核心概念
Vuex官方有五种概念,这里我们只讲常用的三种,State、Mutation、Action。废话太多了还是直接上例子吧。
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
Vue.use(Vuex)
const state = {
cityName:'深圳',
hotList:[]
}
export default new Vuex.Store({
state,
mutations: {
// 选择城市名
selectCity(state, cityName){
state.cityName = cityName;
},
updateHotList(state,hot) {
state.hotList = hot;
}
},
actions:{
//获取hotlist
getHotList(context){
var param = ({
cityname:context.state.cityName
});
axios.get('/api/hostlist',{
params:param
}).then((res) => {
res = res.data.data;
if(res.data.returnCode === '0') {
var val = res.data.returnValue;
//console.log(res.data.returnValue);
context.commit('updateHotList',val);
} else {
context.commit('updateHotList','');
}
});
}
}
});
简单理解,state就是定义需要同步的状态变量。Mutation,提交改变的状态变量。Action,Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作,而Mutation只能包含同步操作。
那么定义状态变量后该如何使用,Mutation又是如何提交的呢。
-
State
由于 Vuex 的状态存储是响应式的,从 store 实例中读取状态最简单的方法就是在计算属性中返回某个状态:
// 在需要用到状态变量的组件
computed:{
cityName(){
return this.$store.state.cityName;//cityName为状态变量
}
也有简便写法:
import { mapMutations, mapState } from 'vuex'
computed:{
...mapState(['cityName'])
}
-
Mutation
可以在组件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用(需要在根节点注入 store)。
//在状态更新的组件中
checkCity(event){
let ele = event.target;
let className = ele.className;
let name = '';
if (className === "mint-indexsection-index" || className ==="mint-indexlist-nav" || className === "mint-indexlist-navitem") {
return;
} else if (className === 'mint-cell-wrapper') {
name = ele.children[0].children[0].innerHTML
} else if (className === "mint-cell-title") {
name = ele.children[0].innerHTML;
} else if (className === 'mint-cell-text') {
name = ele.innerHTML;
}else {
return;
}
this.$store.commit('selectCity', name);
this.$store.dispatch('getHotList');
}
注意:selectCity为上文定义的Mutation函数,name为变量。
-
Action
action 提交的是 mutation,而不是直接变更状态。
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
Vue.use(Vuex)
const state = {
cityName:'深圳',
hotList:[]
}
export default new Vuex.Store({
state,
mutations: {
// 更新hotlist
updateHotList(state,hot) {
state.hotList = hot;
}
},
actions:{
//获取hotlist
getHotList(context){
var param = ({
cityname:context.state.cityName
});
axios.get('/api/hostlist',{ // 异步请求
params:param
}).then((res) => {
res = res.data.data;
if(res.data.returnCode === '0') {
var val = res.data.returnValue;
context.commit('updateHotList',val); // 提交mutation
} else {
context.commit('updateHotList',''); // 提交mutation
}
});
}
}
});
然后在参数cityName改变的地方通过 store.dispatch 方法去触发getHotList方法:
this.$store.dispatch('getHotList');
结语
Vuex的总结到这里就结束了,以上观点仅代表个人观点。如果有错的地方,希望小伙伴能在留言区中指出。源码请移步这是一个仿淘票票项目,由于没有太多精力所以只实现了部分。各取所需吧!
最后想要更加系统的get这一技能,还是需要花点时间去官网学习的。
手打这么多字也不容易,给个好评呗,谢谢咯!