Vue中的数据方法和上下文问题

问题描述 投票:0回答:1

我正在开发的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调用上返回诺言,但无济于事。

vue.js
1个回答
1
投票

这里要注意几个关键事项。

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

要注意的第二点是,使用哪个挂钩加载数据并不重要。挂钩beforeCreatecreatedbeforeMountmounted将在相关阶段同步运行。同时,您的数据正在异步加载。 Vue不会等待,对此不提供任何支持。无论您使用哪个挂钩,数据都不会加载,直到完成初始渲染/安装之后。这是一个常见的问题,您只需要编写组件即可处理首次渲染时丢失的数据即可。

要清楚,我并不是说这些钩子通常是可互换的。他们绝对不是。只是,当您使用AJAX请求加载数据时,使用的内容没有任何实际差异。所有这些钩子都运行之后,AJAX请求将始终返回。因此,在较早的挂钩中执行请求不会使数据在较早的挂钩中可用。

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

© www.soinside.com 2019 - 2024. All rights reserved.