Vuex 通俗版教程


 

144 
作者 Yeaseon 已關注
2017.03.16 16:44* 字數 1245 閱讀 243評論 2

本文基本上是官方教程的盜版,用通俗易懂的文字講解Vuex,也對原文內容有刪減。

如果你對以上聲明不介意,那么就可以繼續看本文,希望對你有所幫助。

學習一個新技術,必須要清楚兩個W,"What && Why"。

"XX 是什么?","為什么要使用 XX ,或者說 XX 有什么好處",最后才是"XX 怎么使用"。

Vuex是什么?

Vuex 類似 Redux 的狀態管理器,用來管理Vue的所有組件狀態。

為什么使用Vuex?

當你打算開發大型單頁應用(SPA),會出現多個視圖組件依賴同一個狀態,來自不同視圖的行為需要變更同一個狀態。

遇到以上情況時候,你就應該考慮使用Vuex了,它能把組件的共享狀態抽取出來,當做一個全局單例模式進行管理。這樣不管你在何處改變狀態,都會通知使用該狀態的組件做出相應修改。

下面講解如何使用Vuex。

最簡單的Vuex示例

本文就不涉及如何安裝Vuex,直接通過代碼講解。

import Vue from 'vue'; import Vuex form 'vuex'; Vue.use(Vuex); const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } } })

以上就是一個最簡單的Vuex,每一個Vuex應用就是一個store,在store中包含組件中的共享狀態state和改變狀態的方法(暫且稱作方法)mutations

需要注意的是只能通過mutations改變store的state的狀態,不能通過store.state.count = 5;直接更改,state相當於對外的只讀屬性。

使用store.commit方法觸發mutations改變state:

store.commit('increment');

console.log(store.state.count) // 1

一個簡簡單單的Vuex應用就實現了。

在Vue組件使用Vuex

如果希望Vuex狀態更新,相應的Vue組件也得到更新,最簡單的方法就是在Vue的computed(計算屬性)獲取state

// Counter 組件 const Counter = { template: `<div>{{ count }}</div>`, computed: { count () { return store.state.count; } } }

上面的例子是直接操作全局狀態store.state.count,那么每個使用該Vuex的組件都要引入。為了解決這個,Vuex通過store選項,提供了一種機制將狀態從根組件注入到每一個子組件中。

// 根組件 import Vue from 'vue'; import Vuex form 'vuex'; Vue.use(Vuex); const app = new Vue({ el: '#app', store, components: { Counter }, template: ` <div class="app"> <counter></counter> </div> ` })

通過這種注入機制,就能在子組件Counter通過this.$store訪問:

// Counter 組件 const Counter = { template: `<div>{{ count }}</div>`, computed: { count () { return this.$store.state.count } } }

mapState函數

computed: {
    count () {
        return this.$store.state.count } }

這樣通過count計算屬性獲取同名state.count屬性,是不是顯得太重復了,我們可以使用mapState函數簡化這個過程。

import { mapState } from 'vuex'; export default { computed: mapState ({ count: state => state.count, countAlias: 'count', // 別名 `count` 等價於 state => state.count }) }

還有更簡單的使用方法:

computed: mapState([
  // 映射 this.count 為 store.state.count 'count' ])

Getters對象

如果我們需要對state對象進行做處理計算,如下:

computed: {
    doneTodosCount () {
        return this.$store.state.todos.filter(todo => todo.done).length } }

如果多個組件都要進行這樣的處理,那么就要在多個組件中復制該函數。這樣是很沒有效率的事情,當這個處理過程更改了,還有在多個組件中進行同樣的更改,這就更加不易於維護。

Vuex中getters對象,可以方便我們在store中做集中的處理。Getters接受state作為第一個參數:

const store = new Vuex.Store({
  state: { todos: [ { id: 1, text: '...', done: true }, { id: 2, text: '...', done: false } ] }, getters: { doneTodos: state => { return state.todos.filter(todo => todo.done) } } })

在Vue中通過store.getters對象調用。

computed: {
  doneTodos () {
    return this.$store.getters.doneTodos } }

Getter也可以接受其他getters作為第二個參數:

getters: {
  doneTodos: state => { return state.todos.filter(todo => todo.done) }, doneTodosCount: (state, getters) => { return getters.doneTodos.length } }

mapGetters輔助函數

mapState類似,都能達到簡化代碼的效果。mapGetters輔助函數僅僅是將store中的getters映射到局部計算屬性:

import { mapGetters } from 'vuex' export default { // ... computed: { // 使用對象展開運算符將 getters 混入 computed 對象中 ...mapGetters([ 'doneTodosCount', 'anotherGetter', // ... ]) } }

上面也可以寫作:

computed: mapGetters([ 'doneTodosCount', 'anotherGetter', // ... ])

所以在Vue的computed計算屬性中會存在兩種輔助函數:

import { mapState, mapGetters } form 'vuex'; export default { // ... computed: { mapState({ ... }), mapGetter({ ... }) } }

Mutations

之前也說過了,更改Vuex的store中的狀態的唯一方法就是mutations

每一個mutation都有一個事件類型type和一個回調函數handler

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

調用mutation,需要通過store.commit方法調用mutation type

store.commit('increment')

Payload 提交載荷

也可以向store.commit傳入第二參數,也就是mutation的payload:

mutaion: {
    increment (state, n) { state.count += n; } } store.commit('increment', 10);

單單傳入一個n,可能並不能滿足我們的業務需要,這時候我們可以選擇傳入一個payload對象:

mutation: {
    increment (state, payload) { state.totalPrice += payload.price + payload.count; } } store.commit({ type: 'increment', price: 10, count: 8 })

mapMutations函數

不例外,mutations也有映射函數mapMutations,幫助我們簡化代碼,使用mapMutations輔助函數將組件中的methods映射為store.commit調用。

import { mapMutations } from 'vuex' export default { // ... methods: { ...mapMutations([ 'increment' // 映射 this.increment() 為 this.$store.commit('increment') ]), ...mapMutations({ add: 'increment' // 映射 this.add() 為 this.$store.commit('increment') }) } }

注 Mutations必須是同步函數。

如果我們需要異步操作,Mutations就不能滿足我們需求了,這時候我們就需要Actions了。

Aciton

相信看完之前的Vuex的內容,你就已經入門了。那么Action就自己進行學習吧(Action有點復雜,我還需要時間消化)。

結語

上個月看Vuex還是一頭霧水,現在看來Vuex也是很容易理解的。

學習一門新技術最重要的就是實踐,單單看教程和demo是遠遠不夠的。

前端路途漫漫,共勉。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM