vue.js v-for list not not updating

时间:2016-10-23 05:17:32

标签: javascript vue.js

我有这个清单:

<ul id="tab">
    <li v-for="list in names">
        {{ list.personName }}
    </li>
</ul>

然后我有了这个vue对象:

var vm = new Vue ({
    el: '#tab',
        data: {
            names: //an object array coming from the server
        }
    });

因此,“名称”数据会更新并从服务器获取信息。但是,当更新/更改名称时,它不会反映在客户端列表中。列表中显示的项目仅反映最初加载页面时的项目。

在谷歌浏览器的vue.js开发人员工具中,我总能看到更新的“名称”数据,但它并没有反映在DOM本身上。

EDIT1 : 'name'中有什么:

names: Array[2]
    0: Object
    _id: "580aeafd017fbfb81a3a794d"
    personName: "hi"

    1: Object
   _id: "580c4455ccc9e39c21f02434"
   personName: "test"

EDIT2

所以我正在使用node.js,并通过socket.io将数据从节点实时传输到客户端,如下所示:

socket.on('userDocument', function(userDocument) {
    var vm= new Vue ({
        el: '#tab',
        data: {
            names: //an object array coming from the server
        }
    });
});

4 个答案:

答案 0 :(得分:15)

在Vue中,阵列更改检测有点棘手。大多数就地数组方法都按预期工作(即在$ data.names数组中进行拼接可以工作),但直接指定值(即$ data.names [0] =&#39; Joe&#39;)不会更新被动渲染的组件。 根据您处理服务器端结果的方式,您可能需要考虑vue文档中描述的这些选项:Array Change Detection

要探索的一些想法:

  • 使用v-bind:key =&#34; some_id&#34;
  • 使用推送添加新元素
  • 使用Vue.set(example1.items,indexOfItem,newValue)(也被Artokun提及)

答案 1 :(得分:3)

如果它作为对象从服务器传入,请确保在对data()进行反应绑定时使用Vue.set(obj,key,value)。

http://vuejs.org/api/#Vue-set

答案 2 :(得分:2)

我不是套接字专家,但这不是处理套接字连接的推荐方法。

套接字与服务器建立持久连接,您可以随时从服务器获取数据。您的Vue()是来自服务器的这些异步数据的处理程序。

在您的示例代码中,每次服务器发送一些数据时,您的消息处理程序似乎都会创建Vue()的新实例。您将很快收到// Initialize your Vue app first: new Vue ({ el: '#tab', template: ` <ul id="tab"> <li v-for="list in names"> {{ list.personName }} </li> </ul> ` data: { names: [] // start with blank, and modify later }, created: function() { // This 'created' hook is called when your Vue instance is setup // TODO: Initialize your socket connection here. // ... // Setup your socket listener mySocketInstance.on("message", response_data => { // Assuming your response_data contains 'user_names' array this.names = response_data.user_names; // Note: 'this' in the above line points to outer scope, that is why we need arrow functions }) } }); 个实例的多个版本,可能会导致用户的浏览器选项卡崩溃,从而占用内存。

我不使用 socket.io ,但根据我对网络应用程序的理解,我希望以下是这样做的:

Vue()

上述代码可能适合您。您仍然需要进行大量的测试和调试。但这就是我期望事情发挥作用的方式。

注意:

  1. 代码示例只创建一个created实例,并在this挂钩中初始化套接字侦听器。因此,套接字消息只有一个侦听器/处理程序。

  2. 套接字消息处理程序使用javascript箭头函数,确保您的外部作用域this与内部作用域names相同。因此,您可以正确更新{{1}}。

答案 3 :(得分:0)

我发现即使你弹出然后将元素推回列表 v-for 也不会更新列表。

例如,代码 this.items.pop(); 将更新列表,但 this.items.push(this.items.pop()); 不会。不知道为什么。

作为解决方案,我做了以下技巧(非常难看,抱歉)并且有效:

<Column v-if="col in columns" ....

methods: {
    refreshColumns() {
        this.columns_temp = [...this.columns];
        this.columns = [];
        this.$nextTick(() => {
            this.columns = [...this.columns_temp];
        });
    },
}

如果我找到合适的解决方案,我会通知您。但目前我没有时间这样做。