3

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

这是一张图片: 渲染表

如您所见,第 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/

4

2 回答 2

0

这种行为似乎是 Vue 虚拟 DOM 算法优化的副作用。当更新发生时,Vue 会尽量减少元素移动,而是重用和修补现有的 DOM 节点。

当您在数据更新后检查 JSFiddle 中生成的 HTML 时,您会注意到<td>第二个中的最后一个<tr>仍然具有 attributes colspan="2" style="text-align: center;",这提示我们该<td>元素已从先前呈现的“In Progress”单元格中错误地重用在v-else. (我不确定这是否可以被描述为 Vue 中的错误......)

无论如何,这个问题有一个解决方法:Vue 有一个特殊的key属性,它给节点差异算法一个关于如何处理元素的提示(参见文档)。<td>在您的示例中,在v-else分支中添加一个键就足够了:

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

这是您的JSFiddle的固定版本

于 2016-11-13T22:29:41.340 回答
0

问题可能与您使用将数据分配给对象的方式有关this.renderings = {...}

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

这可能完美或不完美,具体取决于您使用的数据的嵌套程度,您可以在此处找到有关它的更多信息:https ://vuejs.org/v2/guide/reactivity.html

于 2016-11-13T22:30:27.070 回答