Vue踩坑之旅——Vuex

蘇水軒發表於2018-03-26

問題:某個元件在週期mounted中呼叫了使用computed屬性getter來的全域性變數,該全域性變數為非同步請求的資料,在非路由進入頁面即重新整理該頁面時跳過了store的index.js中的請求資料函式,造成了呼叫資料失敗,得到為空。

          問題修正:  解決: 正在用元件中附加檢測自己請求資料方法解決(有好的 方法可以評論區指教一下:)


原因: 重新整理頁面時仍然是先走app.vue,該非同步請求資料的方法在app的created中呼叫,所以store中的index.js中actions物件中定義的請求資料的方法並沒有被跳過,而是因為元件內第一次呼叫該資料的時候資料為空,拿不到資料,只有請求的資料返回時才會將資料二次set到對應的變數中。

預防: 這裡程式報錯是因為拿來的資料變數為物件型別,在未拿到資料時為undefined,此時對物件內屬性或方法呼叫時就會報錯。應當對需要深層呼叫的變數進行判空處理,防止程式出錯。

延展: 


2018-5-24更新一下:

關於全域性請求來的變數,我們一般放在computed中用語法糖mapGetters來獲取,是因為computed計算屬性是基於它的快取依賴的,當依賴發生變化時,自然變數也就發生了變化。如果我們在元件中需要用到一個基於非同步請求資料的變數時,這個時候就要把它放在computed中。如下例:

我在store中封裝了一個非同步請求的方法

updateData ({ commit }) {    Common.getAssets(ticket).then(response => {        commit('initAssets', response.data.data)      })      .catch(error => {        console.log(error)      })  }複製程式碼

然後在app.vue中呼叫了該方法,隨後在路由的index.vue中getter了對應的全域性變數assets,

這個時候我用到了一個變數叫overNews是由assets陣列和當前日期做了一系列比較判斷後賦值成功的,如果我直接在created中呼叫該方法,那麼這個變數就空了。所以我對assets進行了watch,然後將initOverNews放在監控的執行中。程式碼如下:

initOverNews(){      let overNews = [];      this.assets && this.assets.map(curt => {        if(curt.assetsLeader._id === this.userInfo._id){          if(compareAsc(new Date(), addWeeks(curt.createTime, curt.borrow_data)) === 1){            overNews.push({indexID: curt._id, operateType: '10',createTime: new Date(),  tipsTxt: '資產' +curt.name +  '已超期,請儘快歸還'});          }        }      });      this.$store.commit('initOverMsg', overNews);    }複製程式碼

watch: {    assets: function(){      this.asyncFlag++;    },
//下面的這幾個是做別的判斷,不用理會     msg: function(){      this.asyncFlag++;    },    userInfo: function(){      this.asyncFlag++;    },    asyncFlag: function(){      if(this.asyncFlag>=3){        this.initOverNews();      }    },    msgLength: function(){      this.initPop();    }  }
複製程式碼

computed: {    ...mapGetters([      'assets', 'msg', 'overTipMsg', 'indexFlag', 'userInfo'    ]),    msgLength: function() {      return this.msg?this.msg.length:0 + this.overTipMsg?this.overTipMsg.length:0;    }    // nowUrl: window.location.href  }複製程式碼

同樣,在程式碼裡你也看到了msgLength這個我新增的計算屬性的變數,這樣,在非同步資料來的時候,msgLength就可以隨之更新而更新,同時,因為msgLength的變化而引起的的一系列邏輯處理也可以放在watch中。

小結: 計算屬性是基於它的依賴快取的。計算屬性在它的相關依賴發生改變時會重新取值,所以資料發生變化時,計算屬性的值會進行更新,相關的模板引用也會重新渲染。

             這句話來自某個連結,可以點過去看。

今天就先寫到這,以後有坑持續更新,希望能幫到你們。


相關文章