2016-11-12 204 views
3

我遇到了VueJS渲染的问题。我正在通过Ajax获取数据。在初始渲染时,表格行被渲染为正确的,但是在重新渲染更新的元素时,它不会被正确渲染。VueJS 2重新渲染表

这里有一个画面: Rendered Table

正如你所看到的,列#1呈现的右。但在重新渲染的第2行中,tds被倒置。

这里是我的代码:

var renderings = new Vue({ 
el: '#renderings', 

data: function() { 
    return { 
     hasUnprocessedRenderings: false, 
     renderings: {} 
    }; 
}, 

methods: { 
    clearData: function() { 
     this.renderings = {}; 
    }, 

    updateData: function() { 

     this.$http.get('http://some-url.com/renderings').then(function (response) { 
      this.renderings = response.body.renderings; 
      this.hasUnprocessedRenderings = response.body.hasUnprocessedRenderings; 

      if (this.hasUnprocessedRenderings) { 
       setTimeout(this.updateData, 10000); 
      } 
     }); 

    } 
}, 

mounted: function() { 
    this.updateData(); 
} 

}); 

和我的html:

<div id="renderings"> 
<table class="table table-striped table-hover table-bordered" style="margin bottom: 0;"> 
<thead> 
<tr> 
    <th>Personalisierung</th> 
    <th>Format</th> 
    <th>Download</th> 
    <th></th> 
</tr> 
</thead> 
<tbody> 
<template v-for="rendering in renderings"> 
    <tr> 
     <td>{{rendering.personalizationName}}</td> 
     <td>{{rendering.renderTypeName}}</td> 
     <template v-if="rendering.DOCUMENT_URL"> 
      <td><a :href="rendering.DOCUMENT_URL">{{rendering.DOCUMENT_URL}}</a></td> 
      <td> 
       <ul class="list-inline" style="margin-bottom: 0;"> 
        <li><a :href="'http://some-url.com?pid='+rendering.PROCESS_ID" title="refresh"><i class="fa fa-refresh" aria-hidden="true"></i></a></li> 
        <li><a :href="'http://some-url.com?pid='+rendering.PROCESS_ID" title="delete"><i class="fa fa-trash-o" aria-hidden="true"></i></a></li> 
       </ul> 
      </td> 
     </template> 
     <template v-else> 
      <td colspan="2" style="text-align: center;"> 
       <i class="fa fa-cog fa-spin fa-fw"></i> 
       <span>In Bearbeitung..</span> 
      </td> 
     </template> 
    </tr> 
</template> 
</tbody> 
</table> 
</div> 

所以我的问题:我该如何解决,该行是越来越正确地重新渲染?

感谢您的任何帮助。 :-)

编辑#1: 这里有一个的jsfiddle,那里的问题也会发生:https://jsfiddle.net/dt1kt06g/

+0

除了模板中的语法错误(单引号在' Aletheios

+0

我已经用我的代码和一些数据添加了jsfiddle,并修复了语法错误。问题也出现在那里, – Hendrik

回答

0

看来,如果这种行为是优化在Vue公司的虚拟DOM算法的副作用。发生更新时,Vue会尽量减少元素移动,而是重新使用和修补现有的DOM节点。

当您检查数据更新后您的jsfiddle生成的HTML,你会发现,在第二<tr>最后<td>仍具有属性colspan="2" style="text-align: center;",这给我们一个提示,这个<td>元素已经从错误重复使用先前在v-else中呈现的“进行中”单元格。 (我不确定这是否可以被视为Vue中的错误...)

总之,这个问题有一个解决方法:Vue有特殊的key属性,它给出节点差异算法提示如何处理元素(see documentation)。在你的榜样,在v-else分支添加一个关键<td>足够:

<template v-else> 
    <td colspan="2" style="text-align: center;" :key="rendering.PROCESS_ID"> 
    ... 

Here`s您的jsfiddle的fixed version

+0

Ahhhh非常感谢。 :-)我还发现,如果我删除第二个'template'并直接将'v-else'放入'tr',它似乎也可以工作。 – Hendrik

+0

@Hendrik我想'td'上的'v-else'也会强制Vue重新创建元素,而不是重用它们。 – Aletheios

0

的问题可能与你指定的数据对象使用this.renderings = {...}

要分配对象属性您应该使用Vue.set(this.renderings, key, value)为每个新价值的方式,或this.renderings = Object.assign({}, this.renderings, newData)

这可以很好地工作或不取决于你使用的数据嵌套的数量,你可以在这里找到更多关于它的信息:https://vuejs.org/v2/guide/reactivity.html