vue2.0項目實戰(5)vuex快速入門


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

     以上是vuex的官方文檔對vuex的介紹,官方文檔對vuex的用法進行了詳細的說明。這里就不再細講vuex的各個用法。

       

為什么要用vuex

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

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

下面講解如何使用Vuex。

Vuex的核心

vuex由以下幾部分組成:

  • state             ( state里面就是存放的我們上面所提到的狀態 )
  • mutations      (mutations就是存放如何更改狀態)
  • getters          (getters就是從state中派生出狀態,比如將state中的某個狀態進行過濾然后獲取新的狀態。)
  • actions          (actions就是mutation的加強版,它可以通過commit mutations中的方法來改變狀態,最重要的是它可以進行異步操作。)
  • modules        (modules顧名思義,就是當用這個容器來裝這些狀態還是顯得混亂的時候,我們就可以把容器分成幾塊,把狀態和管理規則分類來裝。這和我們創建js模塊是一個目的,讓代碼結構更清晰。)

 

最簡單的Vuex示例

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

import Vue from 'vue';
import Vuex from '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;直接更改(其實可以更改,不建議這么做,不通過mutations改變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 from '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 } from '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有點復雜,我還需要時間消化)。

 

結語

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

查看跟多內容,請訪問我的獨立博客 https://www.aaz5.com


免責聲明!

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



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