文章目录

什么是Vuex

​Vuex​​:专门在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件,对 vue 应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。

这里的状态我们可以暂且理解为数据

为了更好地理解Vuex我们可以举一个例子:

假如现在A组件有一些数据,B、C、D组件都想要,如果使用全局事件总线我们可以这么做:

Vuex①(简介、原理)_javascript


以上我们只考虑了读取,如果我们现在想修改数据,那么我们就要把修改的数据通过B、C、D组件传给A,如下图所示:

Vuex①(简介、原理)_vue.js_02

可以发现如果我们想要实现某一部分数据在所有(部分)的组件中实现共享是很麻烦的。

而Vuex这个插件可以让共享数据实现的非常轻松!

比如现在我们想把​​x=1​​这个数据共享:

Vuex①(简介、原理)_vue.js_03


我们可以调用特殊的API实现数据的读取修改。

从以上我们可以发现,Vuex的使用场景:

  • 多个组件依赖于同一状态
  • 来自不同组件的行为需要变更同一状态

Vue版求和案例

Vuex①(简介、原理)_数据_04


我们直接写一个Conut组件再在App组件中去引入它,Count组件代码如下:

<template>
<div>
<h1>当前求和为:{{sum}}</h1>
<select v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="increment">+</button>
<button @click="decrement">-</button>
<button @click="incrementOdd">当前求和为奇数再加</button>
<button @click="incrementWait">等一等再加</button>
</div>
</template>

<script>export default {
name:'Count',
data() {
return {
n:1, //用户选择的数字
sum:0 //当前的和
}
},
methods: {
increment(){
this.sum += this.n
},
decrement(){
this.sum -= this.n
},
incrementOdd(){
if(this.sum % 2){
this.sum += this.n
}
},
incrementWait(){
setTimeout(()=>{
this.sum += this.n
},500)
},
},
}</script>

<style lang="css">button{
margin-left: 5px;
}</style>

Vuex的工作原理

Vuex①(简介、原理)_回调函数_05


我们先来看Vuex的三个重要组成部分:

Vuex①(简介、原理)_javascript_06

  • Actions代表动作行为
  • Mutations代表修改、加工、维护
  • state代表状态(数据)

我们说的要把数据交给Vuex进行管理,其实就是把数据交给Vues里的state对象进行管理。

接下来我们可以看到左边的Vue组件,上面带有dispatch的箭头表示我们可以在组件中调用一个名为dispatch的API(就拿上面的案例来说你点完+那个按钮之后,你要在组件里表达出来你要还干什么,而dispatch就充当了这个报信的作用)。

这个词在消息的订阅与发布中提到过,译为“分发,派遣”

dispatch是一个函数,我们在调用它的时候需要传入两个参数:

  • 第一个参数:你要进行的动作类型,是一个字符串
  • 第二个参数:动作的具体内容

例如在上面的案例中,我们要把数字加上2,加就是动作类型,2就是动作的具体内容。

dispatch这个箭头的终点指向的是Actions,这个Actions本质也是一个对象。Actions对象一定会有一个key与dispatch方法中的动作类型对应。

例如:

Vuex①(简介、原理)_前端_07


如上图当你执行完dispatch之后,会立马执行jia对应的回调函数。这个函数调用的时候会收到dispatch的第二个参数2。然后在这个回调函数中我们要自己去调用commit()这个函数:

Vuex①(简介、原理)_javascript_08


commit同样也有两个参数,我们通过这两个参数把行为进行提交,然后我们来到了Mutations,他也是一个Object对象。同样它里面也一定会有对应的key,以及回调函数:

Vuex①(简介、原理)_数据_09

这个回调函数会拿到两个东西:

  • 整个state对象
  • 行为内容(也就是案例中的2)

随后我们在这个回调函数中写上我们的变化要求,state里面的数据就会更新:

Vuex①(简介、原理)_回调函数_10

这个mutate不是API不需要我们去调用

随后Vuex会帮我们重新解析整个组件,然后再去重新渲染 (也就对应着上图的render)

Vuex①(简介、原理)_javascript_11


这里的Actions可以使用Ajax与后端进行交互。也就是说当我们进行一个动作,但是这个动作所对应的值需要发送Ajax请求才能获取的时候,这个Actions就显得尤为重要。但是如果这个值我们是确定的,那么Actions这一步显得有点多余,所以Vuex允许我们在确定值的情况下,在组件中可以直接使用commit()将东西传递给mutations:


Vuex①(简介、原理)_数据_12

同时在我们有一些简单的业务逻辑的时候,这个Actions也是必不可少的

Vuex①(简介、原理)_数据_13


这个Devtools代表Vuex官方的的开发者调试工具,它直接与mutations对话,因为mutations才是真正意义上帮助我们修改state的人。

其实我们可以通过生活中的例子去理解这个过程:

Vuex①(简介、原理)_数据_14


组件相当于客人,Actions相当于服务员,mutations相当于后厨,state相当于菜。客人进门张嘴说话点菜,这个说话就相当于dispatch,服务员记录提交给后厨,也就对应着commit。后厨再去做菜,把菜端上来给客人。而如果客人足够熟悉(也就是明确行为内容)就可以直接跟后厨进行对话,不需要服务员的引导。

另外Vuex的这三个部分都要经过一个人的领导store:

Vuex①(简介、原理)_javascript_15


我们之所以需要它是因为,我们前面调用的dispatch方法是它身上的,commit方法也是它身上的。

这也就意味着我们要让所有的组件实例对象看得到这个store