【问题标题】:Issues with data method & context within VueVue 中的数据方法和上下文问题
【发布时间】:2019-12-08 23:25:01
【问题描述】:

我正在开发的 Vue 应用程序中出现一些奇怪的行为。

在我看来,我最初定义了我的数据:

...
data() {
  return {
    organization: {
      selectedOption: null,
      options: [],
    },
  };
},
...

意图是通过调用我的后端 API 来填充它,我通过 axios 使用 => 表示法:

// The following snippet is in my methods:
...
axios.get('http://localhost:8000/api/org/types')
  .then((response) => {
    Object.keys(response.data).forEach((k) => {
      this.organization.options.push({
        value: k,
        text: response.data[k],
      });
    });

    this.organization.selectedOption = this.organization.options[0].value;
  });
...

数据进来了,我可以看到它确实设置了值,直到我转到视图中的其他位置。

我最初在 beforeMount() 方法中调用了上面的方法,但是我将它移到了 created() 方法中(由于数据上下文/反应性问题),一切似乎都运行良好。

现在我遇到了一个问题,在访问数据时,它似乎总是设置为我定义的初始数据。我正在通过调试/控制台验证这一点。

mounted()内:

console.log(this.organization); // Returns observer that shows the data I would expect to be there via Console, but initial data when accessing anything.
console.log(this.organization.selectedOption); // Returns null

有什么我不明白 Vue 数据方法是如何工作的吗?我的假设是,在创建上下文之后,可以在该视图的生命周期内对基础数据进行变异。

编辑: 我确实尝试在 axios 调用中返回承诺,但无济于事。

【问题讨论】:

  • 您能否将代码放到 jsfiddle 中,并详细说明您的期望,然后得到什么。没有可运行的代码,单词太难理解了。
  • @Huỳnh Lợi Nguyễn 在下面查看我对裙子答案的评论。
  • 我已经阅读了下面的答案并且很喜欢它(当然我也赞成它)。但仍然没有完全解决你的问题。我的总体想法是关于同步性,对下面的答案有基本的想法,但无论如何都没有得到两者之间的联系@@。你说你用.then()解决了它,但我不知道你把它放在哪里了?
  • 啊,我讨厌'谢谢,我修好了' 没有任何细节,就像下一个人一样。抱歉,我所做的是在我的 mounted() 方法中调用了我的 fetching 方法,以 .then(() => ... 结尾,然后正确处理数据,确保最初的承诺。在我的情况下,它正在从我的 API 加载图形和统计数据。与组件上的 v-if 语句一致,到目前为止,它似乎运行良好,没有任何问题。我在阅读时还了解了 updatebeforeUpdate 钩子 - 但我没有尝试它们,因为我的解决方案似乎得到了满足。

标签: vue.js


【解决方案1】:

这里有几个关键点需要注意。

首先,当您将对象记录到控制台时,它是活动的。展开说明这一点的对象后,您可能会看到一个蓝色的小“i”图标。这意味着不复制对象属性。相反,控制台只是对对象的引用。只有当您单击控制台中的对象以展开它时,它才会获取属性值。您可以通过注销 console.log(JSON.stringify(this.organization)) 来解决此问题。

要注意的第二点是,您使用哪个挂钩来加载数据并不重要。钩子beforeCreatecreatedbeforeMountmounted都会在相关阶段同步运行。同时,您的数据正在异步加载。 Vue 不会等待它,不支持它。无论您使用哪个钩子,在初始渲染/安装完成之前都不会加载数据。这是一个常见问题,您只需编写组件,使其能够处理首次呈现时丢失的数据。

需要明确的是,我并不是说这些挂钩通常可以互换。他们绝对不是。只是当您使用 AJAX 请求加载数据时,您使用的并没有任何真正的区别。在所有这些钩子运行后,AJAX 请求总是会返回。因此,在较早的钩子中执行请求不会使数据在后面的钩子中可用。

一种常见的替代方法是在父组件中加载数据,并且仅在加载数据后创建子组件。这通常使用v-if 实现,然后使用道具传递数据。在这种情况下,孩子不必处理丢失的数据。

【讨论】:

  • 我非常感谢您在这里的洞察力,这对我来说更有意义。我感觉它与同步性有关,因为在创建 JSFiddle 时(根据上面的 @Huỳnh Lợi Nguyễn)问题不再存在(参见:jsfiddle.net/stevenfloyd/2obp9vfe/1)。我还能够通过使用 .then(...) 方法来解决它,该方法进一步巩固了它作为一个异步问题。感谢您的帮助和理解。
猜你喜欢
  • 2021-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-12
  • 2018-11-03
  • 2019-09-02
相关资源
最近更新 更多