Vuex狀態管理(上)

Vuex狀態管理(上)

一.概念

vue官方提供的狀態管理器.用於處理全局的數據共享問題的.

​ 狀態:即數據、視圖。狀態管理的本質,就是對應用程序的數據進行科學地流程化管理,目標是讓數據變化可預期、可控。Flux一種數據管理架構方案,這是一種數據管理的思想,最早誕生於React團隊。

  • React技術棧中,最出名的狀態管理工具是 Redux和Mobx。
  • Vue技術棧中,最出名的狀態管理工具是Vuex。

Vuex只是一種數據管理方案,並不是Vue開發必須的。換句話說,在架構Vue項目時可以不使用Vuex。
雖然可以不使用Vuex,但不得不說Vuex非常強大,所以還是建議儘量用上它。Vuex常用於實現組件之間的數據交互、程序數據緩存等需求。Vuex配合devtools,可以非常方便地調試應用程序中的數據bug。

之前我們學習Vue的時候,各種組件之間傳值,比如props傳值,狀態提升傳值,事件總線,還有通過emit事件回傳等等.那我們這裏引入的Vuex,就是組件之間數據交互的終極解決方案.

二.Vuex的倉庫的五大核心概念

1.state

state是Vuex的數據存儲中心

放在state中的數據,所有組件都可以共享,並且保持同步,只要state中的數據發生變化,視圖中自動更新頁面狀態.

2.getters

getters可以理解爲組件中的計算屬性

放在getters關聯的state,只要發生變化,getters 會自動更新

3.mutations

唯一能夠修改state數據的東西,不允許寫異步代碼

mutation直接同步的修改state的主要入口!在組件中使用this.$store.commit(‘已定義的mutaation方法’,‘負載’)來觸發mutation方法

4.actions

間接的異步修改state,在actions裏面的方法都是異步,比如調接口,定時器等.

實際上在actions中可以直接修改state,但是這樣做在devtools沒有修改的記錄,非常不方便於調試

vuex官方建議:只用mutations來修改state,不要使用actions來修改state

5.module

倉庫模塊的拆分

三.安裝與使用

1.安裝

npm install vuex -S

2.使用

在src目錄中新建一個名爲store.js的文件,然後引入vue,vuex,並註冊vue.use(vuex)

//引入vue
import Vue from 'vue';
//import Vuex
import Vuex from 'vuex';
//註冊Vue.use();
Vue.use(Vuex);

const store = new Vuex.Store({
    //Vuex的數據存儲中心
    state:{
        
    },
    //組件中的計算屬性
    getters:{
        
    },
    //唯一能夠修改state數據的東西,不允許寫異步代碼
    mutations:{
        
    },
    //間接的異步修改state,在actions裏面的方法都是異步,比如調接口,定時器等.
    actions:{
        
    },
    //倉庫模塊的拆分
    modules:{
        
    }
});
export default store;

3.main.js引入並掛載

//引入store
import store from './store';

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

4.驗證是否安裝成功

console.log(this.$store);

在任何地方,輸出this.$store即可,比如App.vue的鉤子函數mounted

5.組件中如何使用state和getters

1.方法一

使用掛載到Vue原型上的store,store對象,這個store對象就是new Vuex.Store()生成的倉庫實例對象

console.log(this.$store.state.xxxxxx);
console.log(this.$store.getters.yyyyy);
2.方法二(推薦) computed

使用computed,計算屬性,實際上就是將方案一中獲取到的數據給計算屬性

computed: {
    xxxxxx: function() {
      return this.$store.state.xxxxxx;
    },
    yyyy: function() {
      return this.$store.getters.yyyyy;
    }
  },
3. 方法三(推薦) vuex 輔助函數

就是方案二中的一種優雅寫法,可以認爲是語法糖

組件中從vuex中引入你需要的輔助函數

調用輔助函數,並將其返回的值賦給組件的computed選項

import { mapState, mapGetters } from "vuex";

export default {
  computed: {
    ...mapState(["xxxx", "yyyyy"]),
    ...mapGetters(["culecount"]),
  }
}    

mapState的語法和mapGetters語法

// mapState 接收一個數組做爲參數,參數中的每一項,就是在倉庫中的 state 數據
mapState([state1, state2, state3])

// mapGetters  接收一個數組做爲參數,參數中的每一項,就是在倉庫中的 getter 數據
mapGetters([getter1, getter2])

使用計算屬性和輔助函數取值時的區別?

二者效果一樣,但是在VueDevtools中的表現不一樣

使用計算屬性時,插件中顯示的是computed

使用輔助函數時,插件中顯示的是vuexbindings

雖然效果一樣,但是我們一般推薦使用輔助函數的形式!!!

 computed: {
    //推薦使用展開運算符
    ...mapState(["count", "msg"]),
    ...mapGetters(["culecount"]),
    xxxxxx: function() {
      return this.$store.state.count;
    },
    yyyy: function() {
      return this.$store.getters.culecount;
    }
  },

6.組件中如何修改state與getters的數據

首先要明確一點:state可以修改,getters是不能被修改的

步驟:

  • 倉庫中要提供對應 state修改的mutation函數
  • 在組件中去調用mutation

調用mutationd 的2種方式:

1.方法一

直接使用vuex綁定到vue原型上的$store對象的commit()方法

this.$store.commit()

//在倉庫中的 mutations中定義方法
mutations: {
    //在mutation中定義一個改變state裏參數的方法
    updateCount(state, payload) {
        state.count += payload.count;
    }
}

 //在相應的組件中觸發這個函數
 methods: {
    clickhandle() {
      // 不建議直接改vuex裏的state,雖然可以改,但是不建議
      //this.$store.state.count++;
      let payload = {
        count: 10
      };
      // 向store提交一個名叫updateCount的mutation方法,申請同步改變count
      this.$store.commit("updateCount", payload);
    },
 }
2.方法二(推薦) vuex 輔助函數

使用vuex的輔助函數,mapMutations和

   //在倉庫中的 mutations中定義方法  
   mutations: {
       updateCount(state, payload) {
           state.count += payload.count;
       },
       updateMsg(state,payload){
           state.msg=payload;
       }
   },
       
   //類似解構賦值
   import { mapState, mapGetters, mapMutations, mapActions } from "vuex";
       
   //在組件中使用vuex輔助函數    
   methods: {
   //推薦使用展開運算符
   ...mapMutations(["updateCount", "updateMsg"]),
   ...mapActions(["asyncUpdateCount", "asyncUpdateMsg"]),
   //因展開運算符展開的方法,無法傳參,所以這裏可以使用一個函數做中轉
   update() {
     let payload = {
       count: 10
     };
     this.updateCount(payload);
   },

所有的mutation執行,都能在VueDevtools看到

爲何vuex中的state必須使用mutation來修改呢?

  • 爲了以一種可以預見的方式去修改數據,不至於讓數據難以理解,雖然可以通過$store對象直接修改,但是在嚴格模式下會報錯,並且VueDevtools無法跟蹤到數據,不方便調試
  • 爲了實現調試插件(VueDevtools)的時間旅行機制

7.使用actions異步修改state數據

首先要知道,mutation裏面只允許同步的去修改state數據,

其實mutation中可以異步的去修改state數據,不會報錯,但是會導致調試插件的時間旅行等機制沒有效果

處理異步修改state數據有兩種方式

  • 1.不涉及action,直接在組件上的methods方法中寫異步代碼,然後再調用mutation

  • 2.涉及action

    使用action,首先需要在actions選項中定義action函數

    注意:action中不能直接去修改state,要修改state,必須使用當前上下文對象的commit()去執行某個mutation來修改

使用涉及action修改數據的方式也有兩種

1.方法一

在倉庫中的action中通過commit調用mutation中的方法,然後異步處理,然後在需要調用的組件內部methods選項中,通過 this.$store.dispatch()來派發

 	// actions:間接地異步地修改state
    // 在actions裏面的方法,都是異步,比如調接口、定時器等
    // 在actions中可以直接state,但這樣做在devtools沒有修改的記錄,非常不便於調試
    // Vuex官方特別建議,只用mutations來修改state,不要使用actions來修改state
    actions: {
        asyncUpdateCount(store, payload) {
            setTimeout(() => {
                store.commit('updateCount', payload)
            }, 2000);
        }
    }


	//組件中
    methods: {
     clickAsyncHandle() {
      let payload = {
        count: 10
      };
      // 向store提交一個名叫asyncUpdateCount的actions方法,申請異步改變count
      this.$store.dispatch("asyncUpdateCount", payload);
   	 }
    }
2.方法二

使用Vuex中的輔助函數 mapActions

//類似解構賦值
import { mapState, mapGetters, mapMutations, mapActions } from "vuex"; 
methods: {
    ...mapMutations(["updateCount", "updateMsg"]),
    ...mapActions(["asyncUpdateCount", "asyncUpdateMsg"]),
}

使用方式與上面mutation的方法基本一致!

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