VueJS 2重新渲染表

时间:2016-11-12 13:03:35

标签: vue-resource vue.js vuejs2

我遇到了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/

2 个答案:

答案 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