1.Vuex简介

1.1.Vuex概述

Vuex是一个专门为Vue.js应用程序开发的状态管理模式, 它采用集中式存储管理所有组件的公共状态, 并以相应的规则保证状态以一种可预测的方式发生变化.

试想这样的场景, 比如一个Vue的根实例下面有一个根组件名为App.vue, 它下面有两个子组件A.vue和B.vue, App.vue想要与A.vue或者B.vue通讯可以通过props传值的方式, 但是如果A.vue和B.vue之间的通讯就很麻烦了, 他们需要共有的父组件通过自定义事件进行实现, A组件想要和B组件通讯往往是这样的:

p08_01.png

  1. A组件说: “报告老大, 能否帮我托个信给小弟B” => dispatch一个事件给App
  2. App老大说: “包在我身上, 它需要监听A组件的dispatch的事件, 同时需要broadcast一个事件给B组件”
  3. B小弟说: “信息已收到”, 它需要on监听App组件分发的事件

这只是一条通讯路径, 如果父组件下有多个子组件, 子组件之间通讯的路径就会变的很繁琐, 父组件需要监听大量的事件, 还需要负责分发给不同的子组件, 很显然这并不是我们想要的组件化的开发体验。

  • Vuex就是为了解决这一问题出现的,它相当于提供了一个共享数据存储区域。

1.2.如何在Vue-cli中引入Vuex

  1. 在创建Vue-cli工程时,选择添加Vuex模块,就可以在工程中引入Vuex模块了。
    p08_02.png
  2. 在src文件夹中会出现一个store文件夹,此文件夹中有一个index.js文件,这就是Vuex模块的js文件。 ```javascript import { createStore } from ‘vuex’

// Vuex 数据管理框架 export default createStore({ state: { }, getters: { }, mutations: { }, actions: { }, modules: { } })

  1. 3. main.js文件中,就会自动添加导入store模块和加载store模块的代码
  2. ```javascript
  3. import { createApp } from 'vue'
  4. import App from './App.vue'
  5. import router from './router'
  6. import store from './store'
  7. createApp(App).use(store).use(router).mount('#app')

2.Vuex的使用

Vuex中有五个默认的基本对象:

  • state: state就是Vuex中的公共的状态, 可以将state看作是全局唯一的共享数据仓库。
    类似Vue中的data。(state是所以组件共享的;data是某个组件独有的。)
  • getters: state 的计算属性,类似Vue中的computed 计算属性。
  • mutations:声明方法,用于修改state。类似Vue中的mothods方法。(只能修改同步数据)。
  • actions:声明方法,用于修改state。类似Vue中的mothods方法。(可以修改异步数据)。比如调用api接口都在这里完成。
  • modules:store的子模块,只在开发大型项目的时候会用的上。

思考:state用于存储共享数据,是非常容易理解的。但是,getters、mutations、actions等是做什么用的,有什么必要吗?

2.1.state的使用

  1. 在store文件夹下的index.js文件中写入如下代码: ```javascript import { createStore } from ‘vuex’

export default createStore({ state: { num: 10 }, getters: { }, mutations: { }, actions: { }, modules: { } })

  1. 2. 在两个组件中都添加如下代码:
  2. ```vue
  3. <template>
  4. <div>
  5. <div>这是Home {{$store.state.num}}</div>
  6. </div>
  7. </template>
  8. <script>
  9. export default {
  10. created(){
  11. console.log(this.$store.state.num);
  12. }
  13. }
  14. </script>
  • 两个组件中都会获取state中的数据。

我们也可以对state数据进行修改。

  1. <template>
  2. <div>
  3. <div>这是Home {{$store.state.num}}</div>
  4. <button @click="change">change</button>
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. created(){
  10. console.log(this.$store.state.num);
  11. },
  12. methods:{
  13. change(){
  14. this.$store.state.num = 20;
  15. }
  16. }
  17. }
  18. </script>

上面代码有什么问题吗?

  • 在HomeView.vue文件中,我们通过一个方法修改了state数据。此时我们会发现,其他组件中的state数据也随之改变了。
  • 这是必然的,因为state本来就是所有组件的共享数据。此时问题就出来了。
  • 如果共享数据可以被任何一个组件随意修改的话,此数据将变得非常不安全。

现在我们知道了,为了保证state共享数据的安全,Vuex不希望在某个组件中随意的修改数据,而是希望对共享数据的修改都集中在Vuex中,这样才能监控共享数据的修改,保证它的安全。

getters、mutations、actions这些对象的作用就在于此。

2.2.getters的使用

  1. 在store文件夹下的index.js文件中写入如下代码: ```javascript import { createStore } from ‘vuex’

export default createStore({ state: { num: 10 }, getters: { newnum(state){ return state.num + 10; } }, … })



2.  在组件中添加如下代码: 
```html
...
<h1>{{$store.getters.newnum}}</h1> 
...
  • 组件中就会获取getters中的数据。

2.3.mutations的使用

  1. 在store文件夹下的index.js文件中写入如下代码: ```javascript import { createStore } from ‘vuex’

export default createStore({ state: { num: 10 }, getters: { newnum(state){ return state.num + 10; } }, mutations: { addMethod(state,param){ state.num += param; } }, actions: { }, modules: { } })



2.  在组件中添加如下代码: 
```html
<template>
  <div>   
    <div>这是Home {{$store.state.num}}</div>
    <button @click="change">change</button>
  </div>
</template>

<script>
export default {
  methods:{
    change(){
      this.$store.commit('addMethod',6);
    }
  }
}
</script>
  • 想要访问Vuex中mutations中的方法,需要使用commit方法。此方法有两个参数。
  • 第一个参数:要执行mutations中的方法名。
  • 第二个参数:给执行mutations中的方法传递的参数。

注意:必须要经过commit才能触发 mutation 。

2.4.actions的使用

  1. 在store文件夹下的index.js文件中写入如下代码: ```javascript import { createStore } from ‘vuex’

export default createStore({ state: { num: 10 }, getters: { newnum(state){ return state.num + 10; } }, mutations: { addMethod(state,param){ state.num += param; } }, actions: { addMethod(state,param){ //这里使用setTimeout模拟异步方法 setTimeout(()=>{ state.commit(‘addMethod’,param); },3000); } }, modules: { } })



2.  在组件中添加如下代码: 
```html
<template>
  <div>   
    <div>这是Home {{$store.state.num}}</div>
    <button @click="change">change</button>
  </div>
</template>

<script>
export default {
  methods:{
    change(){
      //this.$store.commit('addMethod',6);
      this.$store.dispatch('addMethod',6);
    }
  }
}
</script>
  • 想要访问Vuex中mutations中的方法,需要使用dispatch方法。此方法有两个参数。
  • 第一个参数:要执行actions中的方法名。
  • 第二个参数:给执行actions中的方法传递的参数。

2.5.总结

现在对Vuex中的state、getters、mutations、actions做一下总结:

  1. state:存放全局共享数据。使用形式:$store.state.num
  2. getters:计算属性。使用形式:$store.getters.newnum
  3. mutations:处理同步数据的方法。使用形式:$store.commit(‘addMethod’,6);
  4. actions:处理异步数据的方法。使用形式:$store.dispatch(‘addMethod’,6);
    • 先使用 $store.dispatch(‘addMethod’,6); 的方式调用Vuex中的actions。
    • actions再使用commit方法调用Vuex中的mutations;