踩坑 :vue2 ajax异步请求数据,层数太多,页面无法渲染

  刚接触vue2不是太久,勉强算是小白一枚吧,在此分享一下我最近踩的一个坑,望以后的小白们借鉴;

  首先,数据结构: 

    data(){

      return {

        outer: {

          mid: [{

            inner: ""

          }]  

        }  

      }

    },

  数据大致就是这样子,反正封了很多层,至于为什么这么分,大概是因为惯性思维的原因,里层的东西一定都是包含于外层,下意识的就这么写了,简直害死人,不过,这些都不是重点,重点在后面的数据更新以及页面渲染,嗯,最开始我是这么写的 

queryInfo (index){
  var condition = ....,
  http.api({
  url: '/tv/orderForm/ClickDetail',
  params: condition,
   successCallback: function (data) {
   this.outer.mid[index].inner = data;
  }.bind(this)
  })
}

(http.api只是公司的老前辈们将ajax请求进行了一下封装,由于这不是重点,就不说了。)
以一个android开发出身的我来看,这代码看上去没毛病啊,但是运行之后发现虽然inner的值确实改变了,但是页面就是不渲染,我靠,这是肿么了,先百度一波,然后代码就成了这样
queryInfo (index){
  var condition = ....;
  http.api({
  url: '/tv/orderForm/ClickDetail',
  params: condition,
   successCallback: function (data) {
   this.$set(this.outer.mid[index], 'inner' ,data);
  }.bind(this)
  })
}
  都说,当数据不是data的第一层,而是包了几层之后,=赋值是不会触发页面渲染的,要用$set(obj,key,val),但是结果还是然并卵,接着百度,偶然之间看到一个标题,vue ajax请求提前渲染什么的,
大致说的是,ajax请求一般是异步的,vue并不知道你在这里发了ajax请求,所以就不会说等到你执行完毕完成赋值之后再渲染,所以值虽然附近去了,但是页面上显示的还是原来的,恩,讲的好有道理啊,但
是木有讲怎么解决啊,于是,下面这个版本的代码又出来了
queryInfo (index){
  var condition = ....;
  var self = this;
  http.api({
  url: '/tv/orderForm/ClickDetail',
  params: condition,
   successCallback: function (data) {
   self.$set(self.outer.mid[index], 'inner' ,data);
  }
  })
}

  就是在发送请求之前,使用一个中间变量将this,也就是vue对象保存了一下,原理是什么的,大家可以看看这个https://segmentfault.com/q/1010000007376594?_ea=1326047,不过,发现这样
写了之候还是没有刷新出来,因为要提前保存this的原因是ajax请求中的this的指的并不是组件了,但是看了一下公司封装的http,通过.bind(this)绑定的就是组件对象,很好,这没毛病,但是,又白忙活
了。擦,郁闷!
  憋了一阵之后,最终版的代码出现了
  <div v-show="false">{{updateLog}}</div>
  data(){
    return {
      updateLog: 1,
      outer: {...}
    }
  }
  queryInfo (index){
    var condition = ....;
    var self = this;
    http.api({
    url: '/tv/orderForm/ClickDetail',
    params: condition,
     successCallback: function (data) {
     self.$set(self.outer.mid[index], 'inner' ,data);
       self.updateLog = self.updateLog + 1;
    }
    })
  }
  大致就是在data的最外层加上了一个updateLog对象,并在template模板中进行了数据绑定,最后在ajax请求中进行了数据更新,促使页面渲染(数据之后一层的时候是会重新渲染的),到这里,问题完美
解决,虽然是取了巧,但是达到了预期的效果。
  所以:以后写数据结构千万不要惯性的一层包一层,能拿出来就拿出来,不能拿出来想办法把它拿出来,实在没办法了,就可以像我这样取个巧了。
  这个坑就踩到这里了,希望对以后来踩坑的小伙伴们有帮助,当然,也欢迎各位大神们的指点:)

补充于18年1月15日: 数据改变页面不刷新,很大可能是因为绑定的数据模型最初是没有这个属性的,如一个 student , 绑定的时候只有 name 和 id 属性,后来在 vue 页面编辑的过程中又给他添加了一个
          age 属性,这是候你的这个 age 变化就不会触发 vue 的页面刷新,所以不要随便在 页面编辑的过程中给你的数据结构添加可能导致页面变化的属性。



posted on 2017-06-26 17:16  秦家十月  阅读(2626)  评论(2编辑  收藏  举报

导航