Javascript Vue.js:如何更新“文件”中的单个项目;列表";-计算财产?

Javascript Vue.js:如何更新“文件”中的单个项目;列表";-计算财产?,javascript,vue.js,vuejs2,Javascript,Vue.js,Vuejs2,我试图确定解决以下问题的最佳模式: 我想显示特定部门的人员列表 我使部门索引成为常规的、被动的Vue属性 我把该部门的人员名单列为计算财产 现在: 我的后端(Mac应用程序)可以发送一个“索引更改时的人员”事件,我必须重新加载单个人员的姓名 但是:person属性是计算属性中的一项(即“people”,请参见下面的代码) 如何更新人员列表中的人员姓名,而这又是一个计算属性(尽管它是通过部门索引+后端调用“计算的”) 我假设我的原始设置有错误。也许人员列表首先不应该是一个计算属性 代码如下

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

  • 我想显示特定部门的人员列表
  • 我使部门索引成为常规的、被动的Vue属性
  • 我把该部门的人员名单列为计算财产
现在:

  • 我的后端(Mac应用程序)可以发送一个“索引更改时的人员”事件,我必须重新加载单个人员的姓名
  • 但是:person属性是计算属性中的一项(即“people”,请参见下面的代码)
如何更新人员列表中的人员姓名,而这又是一个计算属性(尽管它是通过
部门索引
+后端调用“计算的”)

我假设我的原始设置有错误。也许人员列表首先不应该是一个计算属性

代码如下:

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:

从后端触发更新事件
姓名:{{person.Name}
{{message}}
编辑:


在jsbin上尝试一下:

我只是觉得我应该给你一些关于设置的进一步见解:

如果在实际代码中,
listPeopleInDepartment
是一个ajax调用,那么这可能是一个错误的模式。请参见,Vue将识别计算属性中使用的每个属性(包括其他计算属性),并确保在任何属性发生更改时重新计算。在您的情况下,这意味着无论何时
部门索引
发生更改,它都将重新计算
人员

这就是为什么它可能会有问题,因为您必须返回ajax请求的结果,它不能是异步的,因此它将是一个阻塞调用,在页面运行时会导致页面无响应。另外,假设您正在查看部门1,然后更改为2,如果返回到1,则必须重新加载部门1中的人员,因为它没有存储在任何位置

您可能应该实现一些缓存策略,并且只有当数据不可用时才加载ajax,而且也是以非阻塞方式加载的。您可以使用一个数组来实现这一点,该数组存储按部门id索引的部门中的人员数组,并使用
departmentIndex
的观察者来执行以下操作:


你为什么不能为每个人提供一个Id,然后广播它,而不是广播改变了的人的索引?然后你可以在原始的支持列表中找到那个人并在那里更改它。你的例子看起来很复杂。这有什么原因吗?你简化了一些应该这样工作的部分吗?我的意思是你的
假装UpdateEventFromBackend()
调用按钮点击甚至不在你的
Vue
中。您使用的是
new CustomEvent()
,也许您应该改为使用
vm.$emit()
。@MathewJibin:我示例中的“后端”实际上是对服务器的AJAX调用。自定义事件已经在
详细信息
对象中附带了要更新的人的索引,因此我知道要更新什么,只是我不清楚如何更新。@Elfayer:
假装UpdateEventFromBackend
只是一个模拟,从Vue应用程序之外的某个地方显示,可以发出更改事件,并且该事件不受my Vue客户端代码的控制。计算属性仍将使用项目列表,对吗?在该列表中找到该项并在其中进行更新,使计算属性返回引用,而不是创建新对象。更新基础项属性将自动更新绑定。非常感谢您的输入!我的应用程序实际上在嵌入式WebView中作为Mac应用程序运行,因此AJAX调用实际上是对托管应用程序的调用。此时无需添加缓存。我更新了问题以反映这一点。是的,每当部门索引更改时,人员列表必须更新(有上一个/下一个按钮可浏览部门)。
      <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>
function (newValue){
    if (!this.peopleCache[newValue]){
        var that = this;
        //Load it via ajax
        loadPeopleInDepartment(newValue, function(result){
            that.peopleCache[newValue] = result;
        });
    }
}