【问题标题】:Send resolved async data via props from parent to child component - Vue通过 props 从父组件向子组件发送解析的异步数据 - Vue
【发布时间】:2019-09-23 18:19:40
【问题描述】:

父组件:

<template>
  <div>
    <Nav :data="data" />
  </div>
</template>

<script lang="ts">
// ... removed obvious imports for readability
@Component({
  components: {
    Nav: () => import('@/components/Nav.vue')
  }
})
export default class Home extends Vue {
  public nav: NavInterface = {}

  private getData(): Promise<any> {
    // ... this.$http - is an axios instance
    return this.$http
      .getData()
      .then((resp: any) => {
        this.data = resp.data.nav
      })
  }
}
</script>

子组件:

<template>
  <div class="nav">
    <ul>
      <li v-for="(nav, index) in data">{{ nav.id }}</li>
    </ul>
  </div>
</template>

<script lang="ts">
// ... imports
export default class Nav extends Vue {
  @Prop({ default: null }) public readonly data!: NavInterface

  private mounted(): void {
    console.log(this.data) // is undefined, because promise is not resolved yet - this is a problem
  }
}
</script>

有一个问题,当一个 Promise 在父组件中解析时,它不会在子组件中解析。只有在我的getData() 承诺成功解决后,是否可以加载子组件,因为如果没有来自父级的数据,我的子组件就没有意义。

当然,我可以在子组件中使用观察者,然后,我会从承诺中获得正确的数据,但对我来说似乎很麻烦:

@Watch('data')
private onPropChange(val: any) {
  console.log(val) // i get the correct data
}

我更喜欢有条件地渲染我的子组件,只有在 promise 解决之后。

【问题讨论】:

    标签: javascript typescript vue.js


    【解决方案1】:

    下面显示了一个示例方法。您需要根据您的实际要求进行更改:

    <template>
      <div>
        <Nav v-if="isVisible" :items="navItems" />
      </div>
    </template>
    
    export default {
      data() {
        return { navItems: [] };
      },
      computed: {
        isVisible() {
          return this.navItems.length > 0;
        },
      },
      mounted() {
        return this.$http.getData().then(resp => {
          this.data.navItems = resp;
        });
      },
    };
    

    注意:我使用navItems 数组的长度来确定它是否可见。您可能需要使用单独的变量(例如isLoaded)来确定是否应在没有项目或出现错误时呈现Nav

    【讨论】:

    • 我也试过了,但在我的情况下,navItems 是一个空对象,所以它一直给我true...我刚刚使用了Object.keys(navItems).length,它工作了。谢谢。
    【解决方案2】:

    你可以在你的父组件中添加一个 if 语句:

    <template>
      <div>
        <Nav v-if="loaded" :data="data" />
      </div>
    </template>
    

    在函数中:

    return this.$http
          .getData()
          .then((resp: any) => {
            this.data = resp.data.nav
            this.loaded = true
          })
    

    OR if data.nav is null o 填充数据后不存在

        <template>
          <div>
            <Nav v-if="data.nav" :data="data" />
          </div>
        </template>
    

    【讨论】:

      猜你喜欢
      • 2018-11-30
      • 2020-07-26
      • 2018-09-04
      • 2019-08-15
      • 2021-07-26
      • 2020-05-10
      • 1970-01-01
      • 2016-03-18
      • 2019-08-08
      相关资源
      最近更新 更多