Vuex状态更新流程你都会了,面试官敢不给你发offer?
什么是Vuex?Vuex官方解释:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
说到Vuex其实很多小伙伴的项目中基本都引入了,对Vuex的使用其实并不陌生!但面试的时候,面试官突然问起:你对Vuex是怎么理解的?或者怎么看待Vuex?
此刻我估计有些小伙伴回答得还是磕磕盼盼,那么这篇文章就从O到1,再彻底讲一下我对Vuex的理解
首先咱从面试的角度出发?
1.面试官第一个问题:Vuex有哪几种属性?
共有5个核心属性:state,getters,mutations,actions,modules 。小伙伴们这里一定要背哦!不仅要背出来,还要英文发音标准哦。这是必须要装的逼!不然第一题都挂了,就没有然后了!
2.面试官第二个问题:请你说说这几属性的作用?
此时小伙伴们就要注意了,你不能这么回答:state是定义数据的,等同与vue里面的data啥啥啥的... getters又等同与vue里面的计算属性啥啥啥的...
这样回答虽说问题不大,但总又感觉好像差点意思!显得不专业,半吊子(半桶水),培训机构刚那个啥一样(纯属玩笑,没有任何贬低的意思)
咱换个思路,直接从Vuex的使用层面跟面试官去讲!咱先看官网流程图
解析这张图之前咱先想一下,我们怎么获取Vuex里面的数据? 如果配置过Vuex的小伙伴此时就会说:新建store文件->index.js,进行如下配置
//store/index.js
import Vue from 'vue' //引入vue
import Vuex from 'vuex' //引入vuex
Vue.use(Vuex) //在vue里面注入
export default new Vuex.Store({
state: { //存放状态
flag:'我是一个全局变量'
},
})
//全局入口文件main.js
import store from './store/index.js'
new Vue({
store,
...//省
})
这样一个简单的vuex就配置好了。接下来怎么去页面引用呢? 非常简单!
//组件
<template>
<div>{{$store.state.flag}}</div>
</template>
<script>
//省...
</script>
怎么样? 小伙伴们,复杂吗?
那此时小伙伴就问了,那为什么上面那个流程图那么复杂呀?
这里咱就要解开你的疑惑了,上面流程图表述得更多的是教你修改状态。而不是读取状态!。
咱现在要修改Vuex的里面state的flag,小伙伴们怎么改呀?
<template>
<div>{{$store.state.flag}}</div>
<button @click='edit()' >修改</button>
</template>
<script>
export default {
methods:{
edit(){
this.$store.state.flag = '修改全局变量'
},
}
}
</script>
上面这样做能改掉吗? 很明确的告诉你们,能改,但是不建议也不允许这样改!
为什么呢? 没有为什么(可参考这篇博客)!肯定是按照上面流程图的方式走呀。不然要这个流程图干嘛呀?对吧!那按照流程图的意思是,你要改状态,必须在mutations上面定义方法去改! 该怎么改呢?这里咱就要修改一下store文件->index.js
import Vue from 'vue' //引入vue
import Vuex from 'vuex' //引入vuex
Vue.use(Vuex) //在vue里面注入
export default new Vuex.Store({
state: { //存放状态
flag:'我是一个全局变量'
},
mutations:{ //新增mutations配置项,里面写修改状态的方法
Edit(state){
state.flag = '修改全局变量'
}
}
})
完成store文件->index.js文件修改后,咱组件里面使用如下:
<template>
<div>{{$store.state.flag}}</div>
<button @click='edit()' >修改</button>
</template>
<script>
export default {
methods:{
edit(){
this.$store.commit('Edit') //直接调用vuex下面mutations的方法名
},
}
}
</script>
怎么样?伙伴们?简单吗? 咱再回顾一下上面的流程图
咱上面的案例是不是就完全按照流程图的方式修改的状态? 细心的小伙伴很快就发现了,很显然不是呀!
你没经过黄色的Actions 这个玩意啊?
这里要补充说明一下,我之前也被误导了很久。这也是这张图没表明的地方!跟伙伴们这么说吧,黄色的可以省略!什么意思呢? 就是你可以直接从绿色(组件)->红色(mutations)->蓝色(state状态)
就像我们上面的案例:直接在Vue Components组件视图里面,通过 $store.commit 调用 Vuex里面的方法,vuex里面的方法再修改Vuex的数据,总之一句话,Vuex的数据修改,只能Vuex自己来,外人别参与!
那下面咱为了巩固一下这个思想,再次演示一下
//vuex 文件
import Vue from 'vue' //引入vue
import Vuex from 'vuex' //引入vuex
Vue.use(Vuex) //在vue里面注入
export default new Vuex.Store({
state: { //存放状态
flag:'我是一个全局变量'
},
mutations:{ //新增mutations配置项,里面写修改状态的方法
Edit(state,data){ //data是组件传过来的参数
state.flag = data
}
}
})
//vue组件
<template>
<div>{{$store.state.flag}}</div>
<button @click='edit("red")' >红色</button>
<button @click='edit("yellow")' >黄色</button>
<button @click='edit("green")' >绿色</button>
</template>
<script>
export default {
methods:{
edit(color){
this.$store.commit('Edit',color) //commit 有2个参数,第一个是方法名称,第二个参数
},
}
}
</script>
再次通过案例,说明了想要修改Vuex状态。就要遵守Vuex修改流程,把你要修改的值动态传入,就像普通的函数传参一样!只不过,你是通过 $store.commit 调用的函数方法。
好了,讲到这里。其实vuex核心就已经讲完了,因为你们已经知道了,Vuex怎么获取数据,也知道了Vuex怎么修改数据!
伙伴们又要说了,你开始讲了有5个属性!现在才讲2个,一个state,一个mutations? 就这么糊弄?
别急呀,伙伴们。咱也得喝口水嘛! 其实接下来剩下的3个就属于辅助性作用的存在了
什么叫辅助性呢? 因为刚才我们说了,核心已经讲完,你们知道怎么获取,也知道怎么修改。一个状态知道怎么获取,怎么修改。那就是已经完了呀! 剩下的只是说,让你怎么更好的去获取状态,更好的去管理状态,以及特殊情况下怎么修改状态了。
接下来咱先讲特殊情况下怎么修改状态。什么叫特殊情况?异步就叫特殊情况。
咱们刚才的一系列操作,是不是都属于同步操作呀? 那么咱想象一个场景,咱要修改的这个状态一开始是不知道的,什么情况下知道呢?必须调用后端接口,后端返回给你,你才知道! 此时聪明的小伙伴就说了:这还不简单吗? 我直接在函数里面发请求呗!如下
//vuex 文件
import request form '../utils/request.js'
import Vue from 'vue' //引入vue
import Vuex from 'vuex' //引入vuex
Vue.use(Vuex) //在vue里面注入
export default new Vuex.Store({
state: { //存放状态
flag:'我是一个全局变量'
},
mutations:{ //新增mutations配置项,里面写修改状态的方法
Edit(state){
request('/xxx').then(res=>{ //异步请求
state.flag = res.data
})
}
}
})
这样做虽然可以改。但是小伙伴们咱又回到了最初的话题,这样改合规吗?符合流程图流程么?
是不是显然不符合呀,咱刚才讲同步代码修改状态的时候,是不是也特意把Actions提了一嘴?
所以此时Actions作用就在此发挥出来了,废话少说,Actions就是用来定义异步函数的,每当我们要发起请求获取状态,就必须写在这个函数里面,如下:
//vuex 文件
import request form '../utils/request.js'
import Vue from 'vue' //引入vue
import Vuex from 'vuex' //引入vuex
Vue.use(Vuex) //在vue里面注入
export default new Vuex.Store({
state: { //存放状态
flag:'我是一个全局变量'
},
mutations:{ //新增mutations配置项,里面写修改状态的方法
Edit(state){
state.flag = state
}
},
actions:{ //新增actions配置项
GetData({commit}){ //定义获取异步数据的方法
request('/xxx').then(res=>{ //异步请求
commit('Edit',res.data)
})
}
}
})
//vue组件
<template>
<div>{{$store.state.flag}}</div>
<button @click='setData()' >调用异步</button>
</template>
<script>
export default {
methods:{
setData(color){
this.$store.dispatch('GetData') //通过dispatch调用vuex里面的actions下面定义的方法名
},
}
}
</script>
这样一来,是不是就跟流程图彻底对应上了?
在Vue Components组件视图里面,通过 $store.dispatch 调用 Vuex里面的actions下定义的异步方法,然后通过vuex里面的异步 $store.commit 再调用vuex里面的同步方法,最终由同步方法修改状态。
最后总结出:只要涉及到修改状态,必须调用同步里面方法。不管是在组件使用 $store.commit, 还是在 actions 里面使用commit ,都必须调用mutations里面定义的方法 !
通过以上的实例,我相信大家已经明白了整个Vuex修改状态的过程。也对官网的流程图有了更清晰的认知了。
接下来就只剩下2个最简单的属性了,getters与modules
getters类似于vue组件中的computed,进行缓存,对于Store中的数据进行加工处理形成新的数据!直接看实例:
//vuex 文件
import request form '../utils/request.js'
import Vue from 'vue' //引入vue
import Vuex from 'vuex' //引入vuex
Vue.use(Vuex) //在vue里面注入
export default new Vuex.Store({
state: { //存放状态
flag:'我是一个全局变量!',
name:'伙伴们'
},
getters:{ //新增mutations配置项,里面写修改状态的方法
flagName(state){
return state.name + state.flag
}
},
})
//vue组件
<template>
<div>{{$store.state.flagName}}</div>
</template>
<script>
export default {
}
</script>
最后咱们来讲modules,modules针对比较大型的项目时才能发挥优势,不然你项目太小,整个维护的状态都不超过10,那就没必要用modules了!
modules其实就是把Vuex里面的所有功能进行一个更细化的拆分:
//vuex 文件
import request form '../utils/request.js'
import Vue from 'vue' //引入vue
import Vuex from 'vuex' //引入vuex
Vue.use(Vuex) //在vue里面注入
const moduleA = { //组件A需要单独维护的状态
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = { //组件B需要单独维护的状态
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
state:{}, //全局状态
modules: { //整体合并
moduleA: moduleA,
moduleB: moduleB
}
})
//vue组件A
<template>
<div>{{$store.state[moduleA].flag}}</div> //调用Vuex模块里面的状态时,要加moduleA模块名
</template>
<script>
export default {
}
</script>
//vue组件B
<template>
<div>{{$store.state[moduleB].flag}}</div> //调用Vuex模块里面的状态时,要加moduleB模块名
</template>
<script>
export default {
}
</script>
怎么样?小伙伴们。。是不是也挺简单的。
文章到了这里也就把Vuex基本知识都讲完了。小伙伴们需要自己多加练习与消化! 把文章中所讲的Vuex更新状态的流程在脑海里面多回想几遍。有任何疑问,评论区留言吧!
来源:juejin.cn/post/7235603140262084665