1. 程式人生 > >Vuex學習筆記

Vuex學習筆記

最近用到vuex,整理一下基礎用法。

Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式。它採用集中式儲存管理應用的所有元件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。Vuex 也整合到 Vue 的官方除錯工具 devtools extension,提供了諸如零配置的 time-travel 除錯、狀態快照匯入匯出等高階除錯功能。

這個狀態自管理應用包含以下幾個部分:

  • state,驅動應用的資料來源;
  • view,以宣告方式將state對映到檢視;
  • actions,響應在view上的使用者輸入導致的狀態變化。

這裡寫圖片描述

如圖示,Vuex為Vue Components建立起了一個完整的生態圈,包括開發中的API呼叫一環。圍繞這個生態圈,簡要介紹一下各模組在核心流程中的主要功能:

  • Vue Components:Vue元件。HTML頁面上,負責接收使用者操作等互動行為,執行dispatch方法觸發對應action進行迴應。

  • dispatch:操作行為觸發方法,是唯一能執行action的方法。

  • actions:操作行為處理模組。負責處理Vue Components接收到的所有互動行為。包含同步/非同步操作,支援多個同名方法,按照註冊的順序依次觸發。向後臺API請求的操作就在這個模組中進行,包括觸發其他action以及提交mutation的操作。該模組提供了Promise的封裝,以支援action的鏈式觸發。

  • commit:狀態改變提交操作方法。對mutation進行提交,是唯一能執行mutation的方法。

  • mutations:狀態改變操作方法。是Vuex修改state的唯一推薦方法,其他修改方式在嚴格模式下將會報錯。該方法只能進行同步操作,且方法名只能全域性唯一。操作之中會有一些hook暴露出來,以進行state的監控等。

  • state:頁面狀態管理容器物件。集中儲存Vue components中data物件的零散資料,全域性唯一,以進行統一的狀態管理。頁面顯示所需的資料從該物件中進行讀取,利用Vue的細粒度資料響應機制來進行高效的狀態更新。

  • getters:state物件讀取方法。圖中沒有單獨列出該模組,應該被包含在了render中,Vue Components通過該方法讀取全域性state物件。

    Vue元件接收互動行為,呼叫dispatch方法觸發action相關處理,若頁面狀態需要改變,則呼叫commit方法提交mutation修改state,通過getters獲取到state新值,重新渲染Vue Components,介面隨之更新。

全域性資料來源state
改變資料來源的方法mutations
非同步操作方法actions
都放提取出來放到store中,實現全域性資料狀態單獨管理的功能

安裝與配置

1、安裝vuex

使用npm直接安裝

npm install vuex

配置package.json安裝

  "devDependencies": {
    ...
    "vuex": "^2.1.1",
    ...
  },

2、 配置

配置方式和路由的配置方式差不多

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

Vue.use(Vuex)
//建立Store例項
const store = new Vuex.Store({
  // 儲存狀態值
  state: {
    ...
  },
  // 狀態值的改變方法,操作狀態值
  // 提交mutations是更改Vuex狀態的唯一方法
  mutations: {
    ...
  },
  // 在store中定義getters(可以認為是store的計算屬性)。Getters接收state作為其第一個函式
  getters: {
    ...
  },
  actions: { 
    ...
  }
})
// 要改變狀態值只能通過提交mutations來完成

/* eslint-disable no-new */
new Vue({
  el: '#app',
  template: '<App/>',
  components: { App },
  // 將store例項注入到根元件下的所有子元件中
  store
  // 子元件通過this.$store來方位store
})

Vuex 中 Store 的模板化定義:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
  state: {
  },
  actions: {
  },
  mutations: {
  },
  getters: {
  },  
  modules: {

  }
})
export default store

Vuex Store 時關鍵的 5 個屬性:

1. state:

state 定義了應用狀態的資料結構,同樣可以在這裡設定預設的初始狀態。

state: {
  projects: [],
  userProfile: {}
}

我們可以用以下方式在Vue 元件中獲得Vuex的state狀態

template:

<div>
    {{ $store.state.count }}
  </div>

script:

console.log(this.$store.state.count)

2 . actions:
Actions 即是定義提交觸發更改資訊的描述,常見的例子有從服務端獲取資料,在資料獲取完成後會呼叫store.commit()來呼叫更改 Store 中的狀態。可以在元件中使用dispatch來發出 Actions。

actions: {
    LOAD_PROJECT_LIST: function ({ commit }) {
      axios.get('/secured/projects').then((response) => {
        commit('SET_PROJECT_LIST', { list: response.data })
      }, (err) => {
        console.log(err)
      })
    }
  }

注意:
Action 提交的是 mutation,而不是直接變更狀態。
Action 可以包含任意非同步操作。
Action 還是得通過 mutation 方法來修改state

actions: {
  increment (context) {
    context.commit('increment')
  },
  incrementAsync (context) {
    // 延時1秒  
    setTimeout(() => {
      context.commit('increment')
    }, 1000)
  }
},

元件通過commit提交actions的方式來請求改變state

this.$store.dispatch('incrementAsync')

3 . mutations:

mutations: {
    SET_PROJECT_LIST: (state, { list }) => {
      state.projects = list
    }
  }

mutations對state的操作

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      // 變更狀態
      state.count++
    }
  }
})

元件通過commit提交mutations的方式來請求改變state

this.$store.commit('increment')

mutations方法中是可以傳參的,具體用法如下:

 mutations: {
    // 提交載荷 Payload
    add(state, n) {
      state.count += n
    }
  },
this.$store.commit('add', 10)

這裡只是傳了一個數字,在大多數情況下,載荷應該是一個物件,這樣可以包含多個欄位並且記錄的 mutation 會更易讀。

4 . getters:
Getters 允許元件從 Store 中獲取資料,譬如我們可以從 Store 中的 projectList 中篩選出已完成的專案列表

 getters: {
 completedProjects: state => {
  return state.projects.filter(project => project.completed).length
 }
}

getters其實可以認為是 store 的計算屬性,用法和計算屬性差不多。
定義getter:

getters: {
    done(state) {
      return state.count + 5;
    },
  }

使用getter

console.log(this.$store.getters.done)

5 . modules:
modules 物件允許將單一的 Store 拆分為多個 Store 的同時儲存在單一的狀態樹中。