一篇文章带你彻底搞懂Vuex

111 阅读4分钟

Vuex 是什么

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是store仓库。“store” 基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。

  • Vuex 的状态存储是响应式的。 当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会更新。
  • 改变 store 中的状态的唯一途径就是通过 mutation 这样可以方便地跟踪每一个状态的变化。

image.png Vuex为Vue Components建立起了一个完整的生态圈,包括开发中的API调用一环。

(1)流程:

  • Vue Components 是 vue 组件,组件会Dispatch一些事件或动作,也就是图中的 Actions;
  • 在 vuex 中,数据是集中管理的,不能直接去更改数据,所以会把这个动作Commit到 Mutations 中;
  • 然后 Mutations 就去Mutate State 中的数据;
  • 当 State 中的数据被改变之后,就会重新渲染到 Vue Components 中去,组件展示更新后的数据,完成一个流程。

Vuex中action和mutation的区别

mutation中的操作是一系列的同步函数,用于修改state中的变量的的状态。 mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型一个回调函数。这个回调函数就是实际进行状态更改的地方,并且它会接受state作为第一个参数:

const store =createStore({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      state.count++      // 变更状态
    }
  }
})
store.commit('increment')

而Action类似于mutation,不同点在于:

  • Action 可以包含任意异步操作。
  • Action 修改的是 mutation,而不是直接变更状态。
const store =createStore({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
})

Action 函数接受一个与store实例具有相同方法和属性的context对象, 因此你可以调用context.commit来修改mutation,或者通过context.statecontext.getters来获取stategetters。所以,两者的不同点如下:

  • Mutation专注于修改State,是修改State的唯一途径;Action业务代码、异步请求。
  • Mutation:必须同步执行;Action:可以异步,但不能直接操作State。
  • 在发生更新时,先触发actions,actions再触发mutation。

为什么要用 Vuex呢

由于传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致代码无法维护。 所以需要把组件的共享状态抽取出来,以一个全局单例模式管理。 在这种模式下,组件树构成了一个巨大的"视图",不管在树的哪个位置,任何组件都能获取状态或者触发行为。

Vuex有哪几种属性,他们分别是什么?

有五种,分别是 State、 Getter、Mutation 、Action、 Module

  • state => 基本数据(数据源存放地)
  • getters => 从基本数据派生出来的数据
  • mutations => 提交更改数据的方法,同步
  • actions => 包裹了mutations,使之可以异步。
  • modules => 模块化Vuex

为什么 Vuex 的 mutation 中不能做异步操作?

  • Vuex中所有的状态更新的唯一途径都是mutation,异步操作通过 Action 来提交 mutation实现,这样可以方便地跟踪每一个状态的变化。
  • 每个mutation执行完成后都会对应到一个新的状态变更,这样devtools就可以打个快照存下来,然后就可以实现time-travel如果mutation支持异步操作,就没有办法知道状态是何时更新的,无法进行状态的追踪。

Vuex的严格模式

开启严格模式,仅需在创建 store 的时候传入 strict: true

const store = createStore({
  // ...
  strict: true
})

在严格模式下,无论何时发生了状态变更且不是由 mutation 函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。

如何在组件中访问store

访问 State 和 Getter

为了访问 state 和 getter,需要创建 computed 引用以保留响应性。

import { computed } from 'vue'
import { useStore } from 'vuex'

export default {
  setup () {
    const store = useStore()

    return {
      // 在 computed 函数中访问 state
      count: computed(() => store.state.count),

      // 在 computed 函数中访问 getter
      double: computed(() => store.getters.double)
    }
  }
}

访问 Mutation 和 Action

要使用 mutation 和 action 时,只调用 commit 和 dispatch 函数。

import { useStore } from 'vuex'

export default {
  setup () {
    const store = useStore()

    return {
      // 使用 mutation
      increment: () => store.commit('increment'),

      // 使用 action
      asyncIncrement: () => store.dispatch('asyncIncrement')
    }
  }
}