我遇到了VueJS渲染问题。我按照ajax获取数据。在初始渲染时,表格行的渲染是正确的,但在重新渲染更新的元素时,它不会被正确渲染。
这是一张图片: 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: 这是一个小问题,也会出现问题:https://jsfiddle.net/dt1kt06g/
答案 0 :(得分:0)
似乎这种行为是Vue虚拟DOM算法中优化的副作用。发生更新时,Vue会尝试最小化元素移动,而是重用并修补现有DOM节点。
在数据更新后检查JSFiddle中生成的HTML时,您会注意到第二个<td>
中的最后一个<tr>
仍然具有属性colspan="2" style="text-align: center;"
,这给了我们提示此<td>
元素已在v-else
中先前呈现的“进行中”单元格中错误地重复使用。 (我不确定这是否可以被描述为Vue中的错误...)
无论如何,这个问题有一个解决方法:Vue具有特殊的key
属性,它为节点差异算法提供了如何处理元素(see documentation)的提示。在您的示例中,向<td>
分支中的v-else
添加密钥就足够了:
<template v-else>
<td colspan="2" style="text-align: center;" :key="rendering.PROCESS_ID">
...
这是你的JSFiddle的fixed version。
答案 1 :(得分:0)
问题可能与使用this.renderings = {...}
要分配对象属性,您应该为每个新值使用Vue.set(this.renderings, key, value)
,或this.renderings = Object.assign({}, this.renderings, newData)
这可能完美或不完美,具体取决于您使用的数据嵌套程度,您可以在此处找到有关它的更多信息:https://vuejs.org/v2/guide/reactivity.html