[聚合文章] vuex浅入浅出

vue.js 2017-11-19 7 阅读

什么是Vuex?

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

Vuex采用和Redux类似的单向数据流的方式来管理数据。用户界面负责触发动作(Action)进而改变对应状态(State),从而反映到视图(View)上。

  new Vue({
      el: "#app",
      //state 驱动应用的数据源
      data () {
        return { count: 0 }
      },
      //view 以声明方式将 state 映射到视图;
      template: '<div @click="increment">{{ count }}</div>',
      //actions 响应在 view 上的用户输入导致的状态变化。
      methods: {
        increment () {
          this.count++
        }
      }
    })

什么是“状态管理模式”?

让我们从一个简单的 Vue 计数应用开始:

  const store = new Vuex.Store({
      //有哪些状态
      state: {
        count: 0
      },
      actions: {
        incrementAction (store) {
          store.commit('increment')
        }
      },
      //改变,可以通过调用这个改变的方法来修改state的值
      mutations: {
        increment (state) {//这里面的方法的第一个就是state,我们可以直接修改
          state.count++
        }
      }
    })

这个状态自管理应用包含以下几个部分:

state,驱动应用的数据源;
view,以声明方式将 state 映射到视图;
actions,响应在 view 上的用户输入导致的状态变化

但是,当我们的应用遇到多个组件共享状态时,
单向数据流的简洁性很容易被破坏:

  • 多个视图依赖于同一状态。

  • 来自不同视图的行为需要变更同一状态。

对于问题一,传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。对于问题二,我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。
因此,我们为什么不把组件的共享状态抽取出来,以一个全局单例模式管理呢?在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!
另外,通过定义和隔离状态管理中的各种概念并强制遵守一定的规则,我们的代码将会变得更结构化且易维护。
这就是 Vuex 背后的基本思想.

什么情况下我应该使用 Vuex?

虽然 Vuex 可以帮助我们管理共享状态,但也附带了更多的概念和框架。这需要对短期和长期效益进行权衡。
如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 global event bus 就足够您所需了。但是,如果您需要构建是一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

Vuex图解

Backend API: 后端的API
Actions:行为,响应在 view 上的用户输入导致的状态变化。
Mutations: 突变,mutations, 通俗的理解,里面装着一些改变数据方法的集合,这是Veux设计很重要的一点,就是把处理数据逻辑方法全部放在mutations里面,使得数据和视图分离。
State: Vuex 使用单一状态树——是的,用一个对象就包含了全部的应用层级状态。至此它便作为一个“唯一数据源 (SSOT)”而存在。这也意味着,每个应用将仅仅包含一个 store 实例。
Vue Components: Vue的组件
Devtools: 工具
Mutate: 变异,相当于修改
Render: 提供,响应

Commit的问题
**为什么不能直接调用mutation方法,而是必须得通过commit来提交mutation呢?
官方解释道:
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutations 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      // 变更状态
      state.count++
    }
  }
})

你不能直接调用一个 mutation handler。这个选项更像是事件注册:“当触发一个类型为 increment 的 mutation 时,调用此函数。”要唤醒一个 mutation handler,你需要以相应的 type 调用 store.commit 方法:store.commit('increment')

VueComponents—{Dispatch (传入)}—>Actions—{Commit (提交)}-->Mutations—{Mutate(修改)}—>State—{Render(响应)}-->VueComponents

State: 相当于组件里面的data,是用来存放数值。
Getter: 相当于vue里面的computed
Actions: 相当于vue里面的methods

  const store = new Vuex.Store({
      //有哪些状态
      state: {
        count: 3
      },
      // 相当于state的计算属性
      getters: {
        evenOrOdd: state => {
          return state.count % 2 === 0 ? 'even' : 'odd'
        }
      },
      actions: {// 可以包含异步的代码
        incrementAction (store, amount) {
          store.commit('increment', amount)
        },
        decrement ({ commit }) {
          commit('decrement')
        }
      },
      //改变,可以通过调用这个改变的方法来修改state的值
      mutations: {
        increment (state, amount) {//这里面的方法的第一个就是state,我们可以直接修改
          state.count += amount
        },
        decrement (state) {
          state.count--
        }
      }
    })

    var app = new Vue({
      el: "#app",
      computed: {
        counter () {
          return store.state.count
        },
        evenOrOdd () {
          return store.getters.evenOrOdd
        }
      },
      methods: {
        add () {
          store.dispatch('incrementAction', 5)
        },
        decrement () {
          store.dispatch('decrement')
        }
      }
    })

注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。