天天看點

Vuex異步請求 導緻子元件報錯

目錄:

前言:不知道大家有沒有遇到這樣的情況,A元件需要v-model綁定一個依賴于Vuex的資料,通常會直接綁定至Vuex資料源,如下所示是正常的處理流程;

data:
--------
 trimesterId: "", //學期ID
--------
  computed: {
    Term() {
      return this.$store.state.Term; //傳回Vuex依賴值
    }
  },
--------
  mounted() {
    this.Search.trimesterId = this.Term[0].value; //賦初始值
  },

           

問題:

但是如果我們的Vuex資料源是異步請求的,那麼就會遇到Vuex資料還沒有拿到,我們的元件已經被渲染了,如下兩種情況:

①:重新整理目前頁面,并沒有顯示初始綁定值;

Vuex異步請求 導緻子元件報錯

②:從其他頁面進入目前頁面時,顯示正确!

Vuex異步請求 導緻子元件報錯

思考:

第一種情況:重新整理頁面的時候我們的Vuex也會随之重新擷取資料,這裡面包括所有actions的異步請求資料,當重新整理頁面的時候元件擷取到的state的值為空,也就是說元件在異步完成之前就已經完成渲染了,導緻元件的資料沒有來得及渲染。

第二種情況:首先應該想到的是Vuex的狀态是什麼時候擷取到的?答案肯定是created生命周期擷取的,當從另一頁面進入目前頁面時,Vuex資料已經加載完畢、目前元件的依賴值已經存在,是以顯示正常;

思路:

我們最終的效果肯定是需要無論是重新整理還是跳轉,都必須賦初始值并正常顯示下拉内容,那麼Vue的watch監聽就可以拿來做這件事情,關于watch我們通常監聽data裡存在的資料,但依舊可以監聽被computed監聽的資料,當computed的傳回值拿到之後,watch也會監聽到computed變化,當computed變化我們把發生變化的值傳遞給watch,通過watch改變data的初始值,這樣當你重新整理頁面時,Vuex重新觸發,随之computed也會監聽得到,通過watch賦初始值;

---- data ----
 trimesterId: "", //學期ID

--------
  computed: {
    Term() {
      return this.$store.state.Term; //傳回Vuex依賴值
    }
  },

--------
  mounted() {
    this.Search.trimesterId = this.Term[0].value; //賦初始值
  },

---- watch ---- 
Term(val) {
      this.Search.trimesterId = val[0].value; //賦初始值
    }
           

解決關鍵點:

computed:傳回Vuex中依賴資料源;

mounted:在Vuex擷取到值以後 指派給v-model綁定的資料原;

watch:監聽computed是否拿到傳回值,拿到之後遞給v-model綁定;

PS:

其實出現這個問題其根本就是異步問題,渲染提前、資料随後(糧草未動、兵馬先行),但開發中如果不使用Vuex,這樣的問題我們完全可以使用promise很好的解決,但如果使用settimeout去延遲渲染,本地開發不考慮網速、響應等原因,上線後網速多差誰也不知道,是以settimeout不管你寫多長時間的延遲也都是會存在很大問題的,不推薦!

最終效果:

Vuex異步請求 導緻子元件報錯