#### 安裝
關于 Vuex 的具體安裝,就不在這里說了,這個官方還是比較清晰的,[戳此進入](https://vuex.vuejs.org/zh/installation.html)。但是需要注意兩點:
* 在一個模塊化的打包系統中,您必須顯式地通過 `Vue.use()` 來安裝 Vuex,比如:
~~~jsx
mport Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex) // 必須調用此函數來注入 Vuex
~~~
* 當使用全局 script 標簽引用 Vuex 時,就不用那么麻煩了,直接引用進來就好,但要注意引用的先后順序,如下:
~~~xml
// 在 Vue 之后引入 vuex 會進行自動安裝
<script src="/path/to/vue.js"></script>
<script src="/path/to/vuex.js"></script>
~~~
雖然 script 的方式看起來比較自動化,但是接觸得多了,你就會明白模塊化其實才是我們的最佳姿勢。
#### 揭開 Vuex 的神秘面紗
拿到一個工具,我們第一時間需要弄明白的,就是這個工具到底能夠幫助我們解決什么問題。比如錘子,砸得了雞蛋打得了電話,比如蘋果,不但能吃還能玩。那么 Vuex 呢,如果把 Vue.js 比喻成路人(走路的人)的話,那么 Vuex 就是他的桑塔納,如果他想去隔壁買包煙,那走過去就行了,開個車過去反而是一種負擔,但是如果他想去幾十公里的學校采花,那桑塔納就得派上用場了,不然等他走過去,可能花兒都謝了。
當然,類比只是為了告訴我們 Vuex 的價值所在,那么在具體在實際的應用中,**它能干什么?什么時候才需要翻它的牌呢?**
我們先來看一段官方代碼:
~~~kotlin
new Vue({
// state 數據源
data () {
return {
count: 0
}
},
// view 視圖
template: `
<div>{{ count }}</div>
`,
// actions 事件
methods: {
increment () {
this.count++
}
}
})
~~~
這是一個很簡單的增長型計數功能頁面,和 [Vue.js](https://cn.vuejs.org/) 有一腿的,應該秒懂。通過事件 `increment`,實現 `count` 增長,然后渲染到界面上去。
這種方式其實就跟走路買煙一樣,屬于短途效應,官方稱作為「單向數據流」,很好理解。
單向數據流

但是,情況變了,現在有兩個頁面 A 和 B,還有以下兩個要求:
* 要求它們都能對 `count` 進行操控。
* 要求 A 修改了 `count` 后,B 要第一時間知道,B 修改后,A 也要第一時間知道。
怎么辦?稍微有點開發經驗的,就能夠很容易的想到,把數據源 `count` 剝離開來,用一個全局變量或者全局單例的模式進行管理,這樣不就在任何頁面都可以很容易的取到這個狀態了。
是啊,這尼瑪就是 Vuex 背后的思想啊,它干的就是這個事情。是不是有一種被 Vuex 這個高大上的名號所坑害的感覺,不就是全局模型嗎,不用它也同樣可能搞定嘛。
是的,也可以搞定,就像沒有桑塔納,你也可以去學校看花一樣,只是經歷的過程不一樣了。
Vuex 的目的是為了管理共享狀態,為了達到這個目的,它制定了一系列的規則,比如修改數據源 state、觸發 actions 等等,都需要遵循它的規則,以此來達到讓項目結構更加清晰且易于維護的目的。
那么我們再來看看官方的描述:
> Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。它采用集中式存儲管理應用的所有組件的狀態,并以相應的規則保證狀態以一種可預測的方式發生變化。
有沒有瞬間清晰多了。
#### 什么時候翻 Vuex 的牌
其實了解了 Vuex 要干的活以后,什么時候翻牌,那就容易選擇得多了。就像前面的類比一樣,去隔壁買包煙,你還開個桑塔納,找停車位的時間,煙都抽完了。
所以,我們要根據項目的需要,來衡量短期和長期的效益,如果不打算開發大型的單頁應用,那 Vuex 可能還是你的一個負擔。對于一些不大不小的項目,自己又懶得走,開車又覺得麻煩,那你騎個共享單車過去也行嘛。
這里的共享單車指代的是官方中的一個簡單的 [store 模式](https://cn.vuejs.org/v2/guide/state-management.html#%E7%AE%80%E5%8D%95%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86%E8%B5%B7%E6%AD%A5%E4%BD%BF%E7%94%A8),其實就是一個單純的全局對象。
關于全局對象和 Vuex 之間的區別,官方寫得還是比較通俗易懂的:
> Vuex 和單純的全局對象有以下兩點不同:
>
> 1. Vuex 的狀態存儲是響應式的。當 Vue 組件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那么相應的組件也會相應地得到高效更新。
> 2. 你不能直接改變 store 中的狀態。改變 store 中狀態的唯一途徑就是顯式地**提交 (commit) mutation**。這樣使得我們可以方便地跟蹤每一個狀態的變化,從而讓我們能夠實現一些工具幫助我們更好地了解我們的應用。
#### 簡單示例
~~~cpp
// 如果在模塊化構建系統中,請確保在開頭調用了 Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
~~~
> 每一個 Vuex 應用的核心就是 store(倉庫)。store 基本上就是一個容器,它包含著你的應用中大部分的**狀態 (state)**。
注意:如果 mutations 不知道是什么,沒關系,后面會專門講解到,可以單純的理解為只能用它里面的方法來修改 state 中的數據。
~~~jsx
store.commit('increment') // 調用 mutations 中的方法
console.log(store.state.count) // -> 1
~~~
為什么要這樣設計的,官方也給出了具體的原因:
> 我們通過提交 mutation 的方式,而非直接改變 store.state.count,是因為我們想要更明確地追蹤到狀態的變化。這個簡單的約定能夠讓你的意圖更加明顯,這樣你在閱讀代碼的時候能更容易地解讀應用內部的狀態改變。此外,這樣也讓我們有機會去實現一些能記錄每次狀態改變,保存狀態快照的調試工具。有了它,我們甚至可以實現如時間穿梭般的調試體驗。
>
> 由于 store 中的狀態是響應式的,在組件中調用 store 中的狀態簡單到僅需要在計算屬性中返回即可。觸發變化也僅僅是在組件的 methods 中提交 mutation。
如果最后一句話沒看懂,沒關系,下一章馬上就會講到。
#### PS
來點正經的,到這里,第一篇其實就已經寫完了,當然,這里的內容都是我看了官方的教程后,自己的一個理解,如果有理解不到位的地方,歡迎拍磚。