Vue.js:如何更新"列表中的单个项目" - 计算财产?

时间:2016-12-19 07:46:30

标签: javascript vue.js vuejs2

我试图确定解决以下问题的最佳模式:

  • 我想显示特定部门的人员列表
  • 我使部门索引成为常规的,被动的Vue属性
  • 我将部门中的人员列表作为计算属性

现在:

  • 我的后端(一个Mac应用程序)可以派遣一个"人员,索引已更改"事件,我必须重新加载一个人的名字。
  • 但是:person属性是计算属性中的项目(即" people",请参阅下面的代码)。

如何在列表人员列表中更新人员的姓名,而人员列表又是计算属性(虽然它是"计算"来自departmentIndex +后端调用)?

我认为我的原始设置有误。也许人员名单首先不应该是计算属性?

以下是代码:

function pretendUpdateEventFromBackend() {
   var event = new CustomEvent('PersonUpdated', {detail:{index:1, name:'Jimmy'}});

  document.dispatchEvent(event);
}

var backend = {
  // The actual backend is a Mac app with an embedded WebView...
  listPeopleInDepartment(departmentIndex) {
    return [
      {name:'John'},
      {name:'James'},
      {name:'Jane'}
    ];
  }
}

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

  data: {
      message:'',
      departmentIndex:0,
  },

   computed: {

    people() {
      return backend.listPeopleInDepartment(this.departmentIndex);
    }
  },

  created() {
    const me = this;
    document.addEventListener('PersonUpdated', function(e){

      me.message += 'Updated ';

      var personIndex = e.detail.index;
      var newName = e.detail.name;

      // How can I update person in the list of computed people here?
      // Or how can I force a reload of the people list?

      me.message += 'Person at: ' + personIndex + ' new name: ' + newName + "\n";  
    });
  },
});

HTML:

      <button onclick="pretendUpdateEventFromBackend()">Trigger Update Event from Backend</button>

      <div id="app">

        <div class="person" v-for="person in people">
          Name: {{ person.name }}
        </div>

        <pre>{{message}}</pre>

      </div>

修改

在jsbin上试试:http://jsbin.com/guwezoyena/1/edit?html,js,output

1 个答案:

答案 0 :(得分:0)

我只是觉得我应该对你的设置有进一步的了解:

如果listPeopleInDepartment是您实际代码中的ajax调用,则这可能是一个糟糕的模式。请参阅,Vue将识别计算属性中使用的每个属性(包括其他计算属性),并确保在任何更改时重新计算它。在您的情况下,这意味着只要departmentIndex更改,它就会重新计算people

这就是可能有问题的原因,因为你必须返回ajax请求的结果,它不能是异步的,所以它会成为阻塞调用,会导致页面无响应运行。另外,假设您正在查看部门1,然后您更改为2,如果您返回1,则必须重新加载部门1中的人员,因为它不会存储在任何地方。

您应该实现一些缓存策略,并且只有在数据尚未可用时才会加载ajax,也是以非阻塞方式。您可以使用一个数组来实现此目的,该数组存储由部门ID索引的peopleInDepartment数组,以及departmentIndex的观察者,它将执行以下操作:

function (newValue){
    if (!this.peopleCache[newValue]){
        var that = this;
        //Load it via ajax
        loadPeopleInDepartment(newValue, function(result){
            that.peopleCache[newValue] = result;
        });
    }
}