【问题标题】:Passing data to props after asynchronous call in VueVue中异步调用后向props传递数据
【发布时间】:2019-04-04 11:58:35
【问题描述】:

我已经建立了一个简单的 vue 项目来显示问题。我唯一添加的是 axios 包。问题是当我尝试在异步调用后设置子组件的属性时,我无法读取组件中的该属性。如果您查看代码,您会看到我多次控制台日志以显示何时可以获取数据以及何时无法获取数据。请帮我弄清楚我在这里缺少什么。

父母

<template>
  <div id="app">
    <HelloWorld :test_prop="testData" :test_prop2="testData2" :test_prop3="testData3" test_prop4="I work also"/>
    <div>{{testData5}}</div>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'
import axios from 'axios';
export default {
  name: 'app',
  components: {
    HelloWorld
  },
  data() {
    return {
      testData: '',
      testData2: 'I work just fine',
      testData3: '',
      testData5: ''
    }
  },
  created: function(){
    var self = this;
    this.testDate3 = 'I dont work';
    axios.get('https://jsonplaceholder.typicode.com/posts/42').then(function(response){
      //I need this one to work
      self.testData = 'I dont work either';

      self.testData5 = 'I work also';
    });
  }
}
</script>

孩子

<template>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: ['test_prop', 'test_prop2', 'test_prop3', 'test_prop4'],
  data() {
    return {
      comp_data: this.test_prop,
      comp_data2: this.test_prop2,
      comp_data3: this.test_prop3,
      comp_data4: this.test_prop4
    }
  },
  created: function(){
    console.log(this.test_prop);
    console.log(this.test_prop2);
    console.log(this.test_prop3);
    console.log(this.test_prop4);
  }
}
</script>

【问题讨论】:

  • 您好,您似乎在此处复制代码。或者这只是一个糟糕的复制/粘贴,但你的两个组件是相同的。
  • 谢谢我复制错了。
  • 当您更改 testData 值时,您是否希望 comp_data 值发生变化?
  • 只有在最初创建时才会在父级上调用。之后它不需要来自父母的任何数据。在实际项目中,我试图让孩子从父母那里获取初始数据,然后从那时起在内部设置自己。

标签: asynchronous vue.js vue-component


【解决方案1】:

您的 console.log 内部 created 钩子将显示此变量在父组件中的初始状态。这是因为 Parent 的 created 钩子和 Child 的 created 钩子会同时运行。

所以,当你解决你的承诺时,子组件已经被创建了。要了解这种行为,请使用 {{ this.test_prop }} 将您的道具放入模板中。

要解决这个问题,根据您的需要,您可以为您的道具定义一些 默认值 (see) 或使用 v-if 条件渲染您的子组件。就是这样,希望对你有帮助!

【讨论】:

  • 哇,这确实有效。但我不明白为什么。因此,如果将子组件包装在 v-if 中,但假设 api 调用需要 10 秒,则 v-if 检查是否已经发生,所以它不会渲染组件并继续直到下一次渲染?
  • 就是这样! Child 中的 created 钩子仅在 v-if 为 true 时调用,因为 v-if false 不渲染子组件。
  • 所以我猜是因为我将子组件的初始数据设置为任何道具,这只会在 api 调用完成后发生,所以创建钩子需要多长时间并不重要?我理解对了吗?还是因为我使用 axios 异步进行调用并且需要同步执行此操作是否重要。
  • 这取决于你如何使用 v-if 条件。我建议将它与一个变量绑定,该变量将在 承诺解决后为真。去做,不管你的承诺需要多少时间。
【解决方案2】:

在 Vue 创建的钩子中,只有从主组件传递的属性的初始值。因此,主组件中的后续更新(例如您的示例“在 ajax 调用之后”)不会影响子组件数据变量,因为已经发生了子 创建的钩子。
如果您想稍后以一种方式更新数据,您可以这样做:

 watch: {
    test_prop: function(newOne){
      this.comp_data = newOne;
    }
 }

在属性更改中添加 watcher 将更新主组件中属性的最后一个值。

同时编辑错字this.testDate3。我猜应该是this.testData3

【讨论】:

  • 我也使用这种方法。由于 async props 和 created 钩子在父组件的 created 之后立即在子组件中触发,所以 promise 还没有时间解决。有了观察者,当它被解决时,你会得到正确的数据。
猜你喜欢
  • 2017-12-13
  • 1970-01-01
  • 2017-05-08
  • 1970-01-01
  • 2017-12-17
  • 1970-01-01
  • 2017-08-01
  • 2017-05-21
  • 1970-01-01
相关资源
最近更新 更多