Vue從甜小白到皮大佬系列(八) Vuex

閱讀時間預計8分鐘,讀完本文你將收穫以下知識點,記得點贊👍哦~ html

1、啥是Vuex?

Vuex是用來管理Vue的全部組件狀態,說白了就是組件中通訊的一種高級方式。前端

Vuex官方文檔已經講解的很是詳細,建議通讀一遍,本文是本身的學習總結實踐和概括,有些概念和語句借鑑官方。vue

2、爲何使用Vuex?

在以前的文章組件通訊中咱們講了組件中的經常使用通訊方式有props,$emit/v-on,$parent / $children & $refs這三種,他們的侷限性在於只能在父子組件中通訊,不能在兄弟組件中通訊,另外兩種是Bus中央總線發佈訂閱模式能夠在任意組件之間進行通訊,可是若是在大型項目中不免會有些許瓶頸,組件之間的耦合度較高,那麼這時Vuex就恰到好處的出現了,他可以合理的管理各組件中的狀態(通訊,方法捕獲實現,數據傳遞),將狀態從組建中剝離開來,定義和隔離狀態管理中的各類概念並經過強制規則維持視圖和狀態間的獨立性,這樣咱們的代碼將會變得更結構化且易維護。vuex

3、Vuex核心

Vuex提供一個單例Store它就至關於一個容器同樣,包含着你應用中的state公共數據,咱們經過單例Store來統一的按照既定規則來動態的管理這些state,這就是Vuex的核心。api

1.State

state就是一個純對象,上面有一些狀態掛載,並且一個應用應該只有一個statestore.js緩存

export default new Vuex.Store({
 state : {//初始狀態
    name:'極客James', 
    height:180,
    age:27
  } 
})
複製代碼

1.1mapState:

使用 mapState 輔助函數幫助咱們生成計算屬性,在須要通訊的組件中經過import {mapState} from 'vuex'引入輔助函數,而後要在計算屬性computed鉤子裏面進行數據的映射。bash

mapState輔助函數使用的三種方式:

  • 第一種:計算屬性經過箭頭函數取返回值
computed:mapStates({
    name:state=>state.name,
    height:state=>state.name,
    age:state=>state.age
})
複製代碼
  • 第二種方法:利用ES6的...延展特性 (推薦作法)
computed:{
    ...mapState([
        'name',
        'height',
        'age'
    ])
}
複製代碼
  • 第三種方法:利用ES6的...延展特性經過對象取值
computed:{
    ...mapState({
        name:state=>state.name,
        height:state=>state.height,
        age:state=>state.age
    })
}
複製代碼

在組件中取數據app

<template>
  <div class="app">
    <div>我是store裏面的數據姓名:{{name}}</div>
    <div>我是store裏面的數據年齡:{{age}}</div>
    <div>我是store裏面的數據身高:{{height}}</div>
  </div>
</template>
複製代碼

輸出結果:ecmascript

2.Getter

能夠認爲是 store 的計算屬性,就像計算屬性同樣,getter 的返回值會根據它的依賴被緩存起來,且只有當它的依賴值發生了改變纔會被從新計算。異步

2.1mapGetter

mapGetter是getter的一個輔助函數,使用方法和mapState相似,推薦使用延展...來取值.

3.Mutation

Vuex 中的 mutation 很是相似於事件:每一個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調函數 (handler)。這個回調函數就是咱們實際進行狀態更改的地方,而且它會接受 state 做爲第一個參數,同步改變state的惟一方法。

在組件中經過事件方法來進行 同步改變 store中的 state,須要經過 commit提交來響應 mutation中的事件方法。

methods: {
add () {
  Store.commit('increment', { number: 10 });
},
reduce () {
  Store.commit('reduce');
}
}

複製代碼

另一種寫法:對象風格的提交方式

推薦使用常量替代 Mutation 事件類型

還記得在組件通訊中講到的發佈訂閱方法進行組件間通訊,使用常量來定義事件類型嗎?在Vuex中也是很是推薦使用此辦法的,將mutation中的事件常量整合到一個文件夾mutation-type.js中,經過export方式導出.

mutation-type.js

export const ADD = 'ADD'
export const REDUCE = 'REDUCE'
複製代碼

store.js中引入import {ADD,REDUCE} from './mutation-type.js'

import {ADD,REDUCE} from './mutation-type.js'
mutation:{
    [ADD](state,payload) {
        state.age += payload.number;
    },
    [REDUCE](state,payload) {
        state.age --;
    }
}
複製代碼

一樣的在須要的組件中引入import {ADD,REDUCE} from './mutation-type.js'

3.1 mapMutation

mapMutationmutation的輔助函數,和state相似均可以經過...擴展運算來進行直接取值。

4.Action

  • Action 提交的是 mutation,而不是直接變動狀態。
  • Action 能夠包含任意異步操做。

註冊一個簡單的Action,而且從外界傳值。

Action 經過 store.dispatch方法觸發,在Vue組件中:

另外的寫法:參數解構

add({commit}) {
    commit('add');
}
複製代碼

4.1 mapAction

mapActionaction的輔助函數,便於在Vue組件中調用action裏面的事件. 在Vue組件中,能夠經過解構mapAction的方式將映射

methods: {
     ...mapActions([
      'add',
      "reduce"
    ])
}
複製代碼

注意此時:用mapActiono映射方法後須要傳參那麼須要寫在事件觸發的地方上

<button @click="add({number:10})">增長年齡</button>
複製代碼

4.2 組合 Action

組合Action其實就是異步處理多個commit事件,能夠相互調動action,藉助Promise保證了數據狀態的穩定性和有序性。

官方實例:

store.js

在Vue組件中:

store.dispatch('actionA').then(() => {
 
})
複製代碼

在另一個 action 中能夠異步提交事件:

actions: {
  actionB ({ dispatch, commit }) {
    return dispatch('actionA').then(() => {
      commit('someOtherMutation')
    })
  }
}
複製代碼

推薦閱讀:

MDN Promise

async / await

5.Module

當應用變得很是複雜時,store 對象就有可能變得至關臃腫,爲了解決這一問題,咱們能夠將store中的五種狀態剝離成單個的模型,而後經過一個入口引入.通常在項目開發中在src目錄下建立一個store的目錄而後建立如下文件

index.js中引入全部文件,統一掛載在Vuex實例上

main.js中引入 index.js並掛載到實例Vue上

經常使用項目結構:

├── index.html
├── main.js
├── api
│   └── ... # 抽取出API請求
├── components
│   ├── App.vue
│   └── ...
└── store
    ├── index.js          # 咱們組裝模塊並導出 store 的地方
    ├── state.js          # 根級別的 state
    ├── actions.js        # 根級別的 action
    ├── getter.js         # 根級別的 getter
    ├── mutations.js      # 根級別的 mutation
    ├── mutations-type.js # mutation事件常數名
    └── modules
        ├── a.js       # a模塊
        └── b.js       # b模塊
        └── ...
    
複製代碼

掃一掃下面的二維碼,回覆學習便可免費領取最新前端學習資料,也但願在前端進階的路上,咱們一塊兒成長,一塊兒進步!

相關文章
相關標籤/搜索