问题:某个组件在周期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) }) }这个时候我用到了一个变量叫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中。
小结: 计算属性是基于它的依赖缓存的。计算属性在它的相关依赖发生改变时会重新取值,所以数据发生变化时,计算属性的值会进行更新,相关的模板引用也会重新渲染。
这句话来自某个链接,可以点过去看。
今天就先写到这,以后有坑持续更新,希望能帮到你们。