## 類 Flux 狀態管理的官方實現
由于狀態零散地分布在許多組件和組件之間的交互中,大型應用復雜度也經常逐漸增長。為了解決這個問題,Vue 提供 [vuex](https://github.com/vuejs/vuex):我們有受到 Elm 啟發的狀態管理庫。vuex 甚至集成到 [vue-devtools](https://github.com/vuejs/vue-devtools),無需配置即可進行[時光旅行調試](https://raw.githubusercontent.com/vuejs/vue-devtools/master/media/demo.gif)。
### React 的開發者請參考以下信息
如果你是來自 React 的開發者,你可能會對 Vuex 和 [Redux](https://github.com/reactjs/redux) 間的差異表示關注,Redux 是 React 生態環境中最流行的 Flux 實現。Redux 事實上無法感知視圖層,所以它能夠輕松的通過一些[簡單綁定](https://yarnpkg.com/en/packages?q=redux%20vue&p=1)和 Vue 一起使用。Vuex 區別在于它是一個專門為 Vue 應用所設計。這使得它能夠更好地和 Vue 進行整合,同時提供簡潔的 API 和改善過的開發體驗。
## 簡單狀態管理起步使用
經常被忽略的是,Vue 應用中原始`數據`對象的實際來源 - 當訪問數據對象時,一個 Vue 實例只是簡單的代理訪問。所以,如果你有一處需要被多個實例間共享的狀態,可以簡單地通過維護一份數據來實現共享:
``` js
const sourceOfTruth = {}
const vmA = new Vue({
data: sourceOfTruth
})
const vmB = new Vue({
data: sourceOfTruth
})
```
現在當 `sourceOfTruth` 發生變化,`vmA` 和 `vmB` 都將自動的更新引用它們的視圖。子組件們的每個實例也會通過 `this.$root.$data` 去訪問。現在我們有了唯一的數據來源,但是,調試將會變為噩夢。任何時間,我們應用中的任何部分,在任何數據改變后,都不會留下變更過的記錄。
為了解決這個問題,我們采用一個簡單的 **store 模式**:
``` js
var store = {
debug: true,
state: {
message: 'Hello!'
},
setMessageAction (newValue) {
if (this.debug) console.log('setMessageAction triggered with', newValue)
this.state.message = newValue
},
clearMessageAction () {
if (this.debug) console.log('clearMessageAction triggered')
this.state.message = ''
}
}
```
需要注意,所有 store 中 state 的改變,都放置在 store 自身的 action 中去管理。這種集中式狀態管理能夠被更容易地理解哪種類型的 mutation 將會發生,以及它們是如何被觸發。當錯誤出現時,我們現在也會有一個 log 記錄 bug 之前發生了什么。
此外,每個實例/組件仍然可以擁有和管理自己的私有狀態:
``` js
var vmA = new Vue({
data: {
privateState: {},
sharedState: store.state
}
})
var vmB = new Vue({
data: {
privateState: {},
sharedState: store.state
}
})
```

<p class="tip">重要的是,注意你不應該在 action 中 替換原始的狀態對象 - 組件和 store 需要引用同一個共享對象,mutation 才能夠被觀察</p>
接著我們繼續延伸約定,組件不允許直接修改屬于 store 實例的 state,而應執行 action 來分發 (dispatch) 事件通知 store 去改變,我們最終達成了 [Flux](https://facebook.github.io/flux/) 架構。這樣約定的好處是,我們能夠記錄所有 store 中發生的 state 改變,同時實現能做到記錄變更 (mutation)、保存狀態快照、歷史回滾/時光旅行的先進的調試工具。
說了一圈其實又回到了[vuex](https://github.com/vuejs/vuex),如果你已經讀到這兒,或許可以去嘗試一下!
- 寫在前面
- 基礎
- 安裝
- 介紹
- Vue實例
- 模板語法
- 計算屬性和偵聽器
- Class 與 Style 綁定
- 條件渲染
- 列表渲染
- 事件處理
- 表單輸入綁定
- 組件基礎
- 深入了解組件
- 組件注冊
- Prop
- 自定義事件
- 插槽
- 動態組件 & 異步組件
- 處理邊界情況
- 過渡 & 動畫
- 進入/離開 & 列表過渡
- 狀態過渡
- 可復用性 & 組合
- 混入
- 自定義指令
- 渲染函數 & JSX
- 插件
- 過濾器
- 工具
- 生產環境部署
- 單文件組件
- 單元測試
- TypeScript 支持
- 規模化
- 路由
- 狀態管理
- 服務端渲染
- 內在
- 深入響應式原理
- 遷移
- 從 Vue 1.x 遷移
- 從 Vue Router 0.7.x 遷移
- 從 Vuex 0.6.x 遷移到 1.0
- 更多
- 對比其他框架
- 加入 Vue.js 社區
- 開發團隊