Vuex入門簡單易懂系列(一)

在 學習vue 開發中,組件通信一直是一大痛點。
當項目是很簡單的 SPA 或者多入口項目時,可以靠着 vue 自帶的 prop/$emit 進行組件通信;規模再大一些,可以搭配使用 bus 總線進行兄弟組件通信;項目再大一些,出現更復雜的組件關係時,複雜的組件通信可以讓你寫得懷疑人生。
萬幸的是, vue 官方出品了 vuex ,通過全局式的狀態管理,解決了這一痛點。
雖然 vuex 很好用,但是,很多小夥伴和我吐槽 vuex 的文檔和 vue-ssr 的文檔一樣,讓人看得一臉懵逼。

安裝並引入

正常情況下,我們使用 vue-cli3 生成項目時,可以選擇集成 vuex 到項目中。此時, vue-cli3 會自動安裝 vuex ,並在 src 文件夾下生成 store.js 完成 vuex 的引入和配置。
但是,很多同學並沒有使用 vue-cli3 或者生成項目時沒有選擇集成 vuex 。此時,就只能手動安裝並引入 vuex 了。

安裝

由於 vuex 是用於全局狀態管理的,所以,它不僅僅作用於開發環境,而且還要用於生產環境。
顯而易見,安裝 vuex 應該使用 -S 即 --save 命令。
npm install vuex -S

引入

類似於 vue-cli3 生成的項目,我們在 src 文件夾下新建 store.js ,並在其中寫入:

// store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({})

然後,我們只需要在 vue 實例中引入 store.js 中的 Vuex.Store 實例即可:

// main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

new Vue({
  router,
  // 引入store
  store,
  render: h => h(App)
}).$mount('#app')

Vuex的使用

完成了 vuex 的安裝和引入,接下來我們進入 Vuex 的使用。
vuex 中有三要素: state, mutation 以及 action 。它們之間的關係可以用官網那張著名的圖來表示:

clipboard.png

重點來了 (State)

簡單來說, state 表示狀態,類似於 vue 中的 data (其實本質上就是差不多的, vuex 在 vue 的 beforeCreate 鉤子中將 state 混入進 data)。但是,它們又有很大的不同: 在使用者看來, state 是全局的,這得益於 vuex 的設計理念——單一狀態樹。這些我將在後幾篇文章中詳細,現在我們只需要知道 state 是類似於全局下的 data 。
接下來我們通過一個簡單例子來感受下 state :
首先,我們需要修改 store.js 文件,配置 state 。可以看到,我們在生成 Vuex.Store 實例時傳入了實例化選項對象,對象包含一個 state 屬性, state 對象的屬性就是我們定義的全局狀態。
此時,我們定義了一個全局狀態——count ,並將其的初始值設爲1。

// store.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  // 添加state
  state: {
    count: 1
  }
})

接下來,我們需要在組件中引用 count,由於它是全局狀態,我們可以在任何一個組件中使用。爲了展示其威力,我們在兩個不同的組件中使用它。
首先我們在 App.vue 中使用它:
在模板中,我們使用 $store.state.count 引入該全局狀態,沒錯,使用它就是那麼簡單,只需要 以 $store.state.key 的形式調用。

// App.vue
<template>
  <div id="app">
    <div id="nav">
      {{$store.state.count}}
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>
    </div>
    <router-view/>
  </div>
</template>

可以發現, Home 前多出了一個 1 ,這代表着我們成功引入了全局狀態 count 。
接下來我們在 Home.vue 的子組件 HelloWorld.vue 中引入 count 。
相同的引用方式: $store.state.count

// HelloWorld.vue
<template>
  <div class="hello">
    {{$store.state.count}}
  </div>
</template>

可以發現,success。

Mutation

但是,上面的示例有個問題,那就是全局狀態是靜態的。如果在實際應用場景中,一般來說,會經常更改狀態。
有的同學會說,我們直接在方法中修改 this.$store.state.key 的值不就行了嗎?
不好意思,當然是不行的。
state 和 data 的另一大區別在於,你不能直接改變 state 。改變 store 中的狀態的唯一途徑就是顯式地提交 (commit) mutation。這樣使得我們可以方便地跟蹤每一個狀態的變化,從而讓我們能夠實現一些工具幫助我們更好地瞭解我們的應用。
簡而言之,我們把 mutation 當做接收 state 作爲參數並修改 state 的自定義事件即可,上一段所說的 commit 就是觸發 mutaion 這個自定義事件的方法。
光說不練假把式,接下來,我們對爲 vuex 添加上 mutation ,實現 state 的動態改變:
首先,當然是修改生成 Vuex.Store 示例的選項對象,爲其添加 mutations 。

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

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    count: 1
  },
  // 添加mutation
  mutations: {
    increment (state) {
      state.count++
    }
  }
})

在上面的代碼中,我們添加了一個名爲 increment 的 mutation 。完成了自定義事件,接下來,我們只需要在組件中對 mutation 進行觸發即可。
我們在 HelloWorld.vue 添加一個按鈕,每次點擊觸發一次 increment 這個 mutation 。可以發現,觸發方式很簡單,只需要調用 store 自帶的 commit 方法,其中參數爲需要觸發的 mutation 的名稱。

// HelloWorld.vue
<template>
  <div class="hello">
    <div>{{$store.state.count}}</div>
    <button @click="$store.commit('increment')">修改count</button>
  </div>
</template>

點擊頁面中的按鈕,你會發現,頁面中的兩個 count 都同時增加了1,說明我們成功實現了 state 的動態修改。

Action

action 類似於 mutation ,也相當於一種自定義事件。只不過, action 操作的是 mutation 而不是 state 。
添加 action 的方法類似,在選項對象中新增 action 屬性即可。與 mutation 的參數不同, action 的參數就是當前創建的 Vue.store 對象實例的上下文,一般將其命名爲 context 。我們需要使用其自帶的 commit 方法來觸發 mutation 。
下面我通過實際的例子來嘗試下 action :
首先,修改選項對象,使得新添加的 action 可以觸發之前的 mutation :

// store.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment ({ commit }) {
      commit('increment')
    }
  }
})

由於我們一般來說僅僅需要 context 中的 commit 方法,所以可以採用解構的方式,直接調用 commit 方法,而不需要以 context.commit 的方式使用它。
接下來,只需要修改 HelloWorld.vue ,使其能夠在點擊按鈕時觸發即可。
action 的觸發方式和 mutation 類似,只不過調用的方法是 dispatch 。

// HelloWorld.vue
<template>
  <div class="hello">
    <div>{{$store.state.count}}</div>
    <button @click="$store.dispatch('increment')">修改count</button>
  </div>
</template>

點擊頁面按鈕,你會發現,實現了和之前相同的效果。

總結

學會了 vuex 三jian客: state , mutation , action ,我們再回過頭看看前面的那張關係圖,此時應該很容易理解了吧?
組件交互觸發 action , 在 action 中進行異步操作(可選)並觸發 mutation , mutation 控制 state 的變動, state 修改之後,觸發響應式,重新渲染組件。
PS(其他的進階用法,如: getter , module , 簡寫以及 vuex 項目結構優化,甚至 vuex 源碼解析將會在之後的文章一一講解)

最後

個人認爲對很多新手在入門時(不管學習什麼東西),無可厚非最好剛開始是看視頻。So,一份付出一份收穫。如果你有需要購買學習視頻的可以訪問該網站加羣http://www.wantmore.top,也可以直接添加羣號:157285015。偶爾會分享學習乾貨噢!

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