Vue反应数据显示为观察者,而不是实际值

时间:2019-07-16 16:06:00

标签: javascript vue.js vue-component reactive

我在组件中有一些方法:

  created() {
    return this.getConversation(this.$route.params.ConversationId).then(
      respConversation => {
        this.conversation = respConversation;
      }
    );
  },
  mounted() {
    console.log(this.conversation);
    return this.getConversationTranscripts(this.conversation.AudioId);
  },

但是,this.conversation打印为{__ob__: Observer}并且没有AudioId

this.getConversationthis.getConversationTranscripts都返回承诺。

1 个答案:

答案 0 :(得分:3)

从Vue的生命周期挂钩中返回承诺并没有多大作用。当然,这不会使他们等待Promise完成。使用async / await也是一样。

内部使用callHook调用钩子,例如callHook(vm, 'mounted')。您可以在以下位置查看callHook的代码:

https://github.com/vuejs/vue/blob/b7c2d9366cf731a1551286b8ac712e6e0905070e/src/core/instance/lifecycle.js#L336

这会调出invokeWithErrorHandling,您可以在以下位置看到它:

https://github.com/vuejs/vue/blob/b7c2d9366cf731a1551286b8ac712e6e0905070e/src/core/util/error.js#L36

尽管invokeWithErrorHandling对于处理返回的任何承诺确实有一些最小的支持,但是callHook会忽略这些承诺。

在问题所示的代码中,将调用created钩子,然后是mounted钩子。 then上的getConversation直到稍后才会被调用,因为它将是异步的。

因此在点mounted被称为this.conversation的值将仍然是其初始值,大概是一个空对象。 Vue的反应性系统将导致其在控制台中显示为{__ob__: Observer}

如果组件需要该数据才能运行,则父级将必须负责加载该数据并延迟创建组件,直到数据可用为止。

组件首次呈现时,很有可能只需要处理丢失的数据。然后,它将需要使用Promises将异步调用链接在一起:

created() {
  this.getConversation(this.$route.params.ConversationId).then(
    respConversation => {
      this.conversation = respConversation;
      this.getConversationTranscripts(this.conversation.AudioId);
    }
  );
}

在这里使用async / await可能会更干净:

async created() {
  this.conversation = await this.getConversation(this.$route.params.ConversationId)
  this.getConversationTranscripts(this.conversation.AudioId);
}

这些都不会使组件的生命周期暂停,因此渲染将继续进行,this.conversation仍设置为其初始值,并且必须对该模板进行编码以对其进行处理。

我要补充一点,使用this.$route.params.ConversationId是不理想的。如果可能的话,这将通过道具注入。当该值更改时,您还需要非常小心。如果值更改导致创建了新组件,那么没问题,但是如果仅更新现有组件,则可能会遇到问题。 createdmounted钩子在第一次创建组件时仅运行一次,因此在参数更改时重用同一组件不会再次运行它们。