Vuex白話教程第一講:Vuex到底是個什麼鬼?

 

先說兩句

官方已經有教程了,爲什麼還要寫這個教程呢?說實話,還真不是我閒着蛋疼,官方的教程真的是太官方了,對於剛入門 Vuex 的童鞋來說,想必看官方的教程,很多地方就如同看聖經一樣,比如「歐瑪尼瑪尼牙」,所有的字都認識,就是不知道說些什麼玩意,不信,你可以戳進去看看

當然,對於大神級別一看就懂的,那就不用說了,肯定是看官方的更權威。還有,如果對 FluxReduxThe Elm Architecture 比較熟悉的話,也可以移步官方,因爲官方也說了,Vuex 的套路基本上都是從那邊吸取整合後,過渡而來的,只不過,Vuex 只鍾情於 Vue.js 罷了。

我之所以寫這個教程,主要是因爲自己剛剛開始和 Vuex 打交道的時候,痛過了、苦過了、傷過了,所以痛定思痛,爲了能讓自己更好的駕馭 Vuex,也爲了不讓新來的童鞋們被 Vuex 調戲過後無處訴苦,所以方纔決定把官方的這些抽象的文字和概念,用連你身後的鼓勵師小姐姐都能看懂的語言,分享出來,助你在前端的道路上越走越順,順利的找到一份有鼓勵師陪伴的工作。

再說一句

Vuex 是 Vue.js 的座駕,所以,如果還不懂 Vue.js 的話,那還是先把 Vue.js 勾搭上了再帶過來一起坐坐吧。當然,既然能夠溜達到這裏,想必跟 Vue.js 起碼也已經是朋友了吧。

有點囉嗦,不要嫌棄,寫教程需要有點前戲,畢竟是第一次。

安裝

關於 Vuex 的具體安裝,就不在這裏說了,這個官方還是比較清晰的,戳此進入。但是需要注意兩點:

  • 在一個模塊化的打包系統中,您必須顯式地通過 Vue.use() 來安裝 Vuex,比如:

 

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)  // 必須調用此函數來注入 Vuex
  • 當使用全局 script 標籤引用 Vuex 時,就不用那麼麻煩了,直接引用進來就好,但要注意引用的先後順序,如下:

 

// 在 Vue 之後引入 vuex 會進行自動安裝
<script src="/path/to/vue.js"></script>
<script src="/path/to/vuex.js"></script>

雖然 script 的方式看起來比較自動化,但是接觸得多了,你就會明白模塊化其實才是我們的最佳姿勢。

揭開 Vuex 的神祕面紗

拿到一個工具,我們第一時間需要弄明白的,就是這個工具到底能夠幫助我們解決什麼問題。比如錘子,砸得了雞蛋打得了電話,比如蘋果,不但能喫還能玩。那麼 Vuex 呢,如果把 Vue.js 比喻成路人(走路的人)的話,那麼 Vuex 就是他的桑塔納,如果他想去隔壁買包煙,那走過去就行了,開個車過去反而是一種負擔,但是如果他想去幾十公里的學校採花,那桑塔納就得派上用場了,不然等他走過去,可能花兒都謝了。

當然,類比只是爲了告訴我們 Vuex 的價值所在,那麼在具體在實際的應用中,它能幹什麼?什麼時候才需要翻它的牌呢?

我們先來看一段官方代碼:

 

new Vue({
  // state  數據源
  data () {
    return {
      count: 0
    }
  },
  // view  視圖
  template: `
    <div>{{ count }}</div>
  `,
  // actions  事件
  methods: {
    increment () {
      this.count++
    }
  }
})

這是一個很簡單的增長型計數功能頁面,和 Vue.js 有一腿的,應該秒懂。通過事件 increment,實現 count 增長,然後渲染到界面上去。

這種方式其實就跟走路買菸一樣,屬於短途效應,官方稱作爲「單向數據流」,很好理解。

單向數據流

但是,情況變了,現在有兩個頁面 A 和 B,還有以下兩個要求:

  • 要求它們都能對 count 進行操控。
  • 要求 A 修改了 count 後,B 要第一時間知道,B 修改後,A 也要第一時間知道。

怎麼辦?稍微有點開發經驗的,就能夠很容易的想到,把數據源 count 剝離開來,用一個全局變量或者全局單例的模式進行管理,這樣不就在任何頁面都可以很容易的取到這個狀態了。

是啊,這尼瑪就是 Vuex 背後的思想啊,它乾的就是這個事情。是不是有一種被 Vuex 這個高大上的名號所坑害的感覺,不就是全局模型嗎,不用它也同樣可能搞定嘛。

是的,也可以搞定,就像沒有桑塔納,你也可以去學校看花一樣,只是經歷的過程不一樣了。

Vuex 的目的是爲了管理共享狀態,爲了達到這個目的,它制定了一系列的規則,比如修改數據源 state、觸發 actions 等等,都需要遵循它的規則,以此來達到讓項目結構更加清晰且易於維護的目的。

那麼我們再來看看官方的描述:

Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的所有組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。

有沒有瞬間清晰多了。

什麼時候翻 Vuex 的牌

其實瞭解了 Vuex 要乾的活以後,什麼時候翻牌,那就容易選擇得多了。就像前面的類比一樣,去隔壁買包煙,你還開個桑塔納,找停車位的時間,煙都抽完了。

所以,我們要根據項目的需要,來衡量短期和長期的效益,如果不打算開發大型的單頁應用,那 Vuex 可能還是你的一個負擔。對於一些不大不小的項目,自己又懶得走,開車又覺得麻煩,那你騎個共享單車過去也行嘛。

這裏的共享單車指代的是官方中的一個簡單的 store 模式,其實就是一個單純的全局對象。

關於全局對象和 Vuex 之間的區別,官方寫得還是比較通俗易懂的:

Vuex 和單純的全局對象有以下兩點不同:

  1. Vuex 的狀態存儲是響應式的。當 Vue 組件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那麼相應的組件也會相應地得到高效更新。
  2. 你不能直接改變 store 中的狀態。改變 store 中狀態的唯一途徑就是顯式地提交 (commit) mutation。這樣使得我們可以方便地跟蹤每一個狀態的變化,從而讓我們能夠實現一些工具幫助我們更好地瞭解我們的應用。

簡單示例

 

// 如果在模塊化構建系統中,請確保在開頭調用了 Vue.use(Vuex)
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})

每一個 Vuex 應用的核心就是 store(倉庫)。store 基本上就是一個容器,它包含着你的應用中大部分的狀態 (state)

注意:如果 mutations 不知道是什麼,沒關係,後面會專門講解到,可以單純的理解爲只能用它裏面的方法來修改 state 中的數據。

 

store.commit('increment') // 調用 mutations 中的方法
console.log(store.state.count) // -> 1

爲什麼要這樣設計的,官方也給出了具體的原因:

我們通過提交 mutation 的方式,而非直接改變 store.state.count,是因爲我們想要更明確地追蹤到狀態的變化。這個簡單的約定能夠讓你的意圖更加明顯,這樣你在閱讀代碼的時候能更容易地解讀應用內部的狀態改變。此外,這樣也讓我們有機會去實現一些能記錄每次狀態改變,保存狀態快照的調試工具。有了它,我們甚至可以實現如時間穿梭般的調試體驗。

由於 store 中的狀態是響應式的,在組件中調用 store 中的狀態簡單到僅需要在計算屬性中返回即可。觸發變化也僅僅是在組件的 methods 中提交 mutation。

如果最後一句話沒看懂,沒關係,下一章馬上就會講到。

PS

來點正經的,到這裏,第一篇其實就已經寫完了,當然,這裏的內容都是我看了官方的教程後,自己的一個理解,如果有理解不到位的地方,歡迎拍磚。

 

更多關於ES6資料

https://www.runoob.com/w3cnote/es6-tutorial.html

https://es6.ruanyifeng.com/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章