state.md 2.9 KB

State

单状态树

Vuex 使用 单状态树(single state tree) —— 也就是单个对象包含整个应用的状态。这使得我们能够方便地定位某一部分特定的状态,在 debugging 的过程中也能轻易地取得当前应用的状态快照(snapshots)。

单状态树和模块化并不冲突 —— 在往后的章节里我们会讨论如何将状态管理分离到各个子模块中。

在 Vue 组件中获得 Vuex State

和 Vue 实例中的 data 对像一样,state 对象一旦进入 Vuex store,就会被 Vue.js 改造成响应式对象(参见 Vue.js 响应系统)。因此,要让 Vuex store 的 state 来驱动 Vue 组件的渲染,只需要简单地在一个计算属性中返回 store.state 中需要的部分即可:

// 一个 Vue 组件模块内部

// 引入一个 vuex store 实例
import store from './store'

export default {
  computed: {
    message () {
      return store.state.message
    }
  }
}

我们并不需要建立任何监听器或者用一个 API 去建立组件和 store 之间的联系 - Vue 的响应式系统会确保界面的自动更新。唯一要记住的是,在计算属性里,必须通过 store.state.xxx 引用 state。不要在计算属性外部存放 state 的引用。

Flux 相关:这里计算属性的用法可以和 Redux 的 mapStateToProps 以及 NuclearJS 的 getters 做类比。

你可能会问为什么我们不直接用 data 去绑定 state,我们看以下例子:

export default {
  data () {
    return {
      message: store.state.message
    }
  }
}

因为 data 函数不追踪任何响应式依赖, 我们得到的仅仅是一个对 store.state.message 的静态引用。即使之后 state 被改变,组件也无法知道它的改变。而计算属性则不同,它在求值时会自动跟踪依赖,因此当状态改变时会自动触发更新。

组件不允许直接改变 state

使用只读的计算属性有一个好处就是,能更好的遵守 组件不允许直接改变 store state 的准则。由于我们希望每一次状态的变动都意图清晰且可被跟踪,因此所有的全局状态变动都必须在 store 的 mutation handlers 当中执行。

为了践行这条准则,在 严格模式 中如果在 mutation handlers 外部改变 Vuex store state,Vuex 会抛出错误。

根据这条准则,我们的 Vue 组件处理的事情就很少了:它们只需要通过只读的计算属性和 store 内部的 state 建立联系,而改变 state 的唯一方法就是调用 actions. 组件依然能在必要时拥有和操作自己的本地状态,但我们再也不需要在组件里包含任何与全局状态相关的逻辑了。