How to display async data in vue template

2020-04-07 07:40发布

I'm interesting in the case of displaying in vue template data which loaded asynchroniously. In my particular situation I need to show title attribute of product object:

<td class="deals__cell deals__cell_title">{{ getProduct(deal.metal).title }}</td>

But the product isn't currently loaded so that the title isn't rendered at all. I found a working solution: if the products aren't loaded then recall getProduct function after the promise will be resolved:

getProduct (id) {
  if (!this.rolledMetal.all.length) {
    this.getRolledMetal()
      .then(() => {
        this.getProduct(id)
      })
    return {
      title: ''
    }
  } else {
      return this.getRolledMetalById(id)
  }
}

However maybe you know more elegant solution because I think this one is a little bit sophisticated :)

2条回答
够拽才男人
2楼-- · 2020-04-07 08:29

I always use a loader or a spinner when data is loading!

<template>
    <table>
        <thead>
            <tr>
                <th>One</th>
                <th>Two</th>
                <th>Three</th>
            </tr>
        </thead>
        <tbody>

            <template v-if="loading">
                <spinner></spinner> <!-- here use a loaded you prefer -->
            </template>

            <template v-else>
                <tr v-for="row in rows">
                    <td>{{ row.name }}</td>
                    <td>{{ row.lastName }}</td>
                </tr>
            </template>

        </tbody>
    </table>
</template>

And the script:

<script>
    import axios from 'axios'
    export default {
        data() {
            return {
                loading: false,
                rows: []
            }
        },
        created() {
            this.getDataFromApi()
        },
        methods: {
            getDataFromApi() {
                this.loading = true
                axios.get('/youApiUrl')
                .then(response => {
                    this.loading = false
                    this.rows = response.data
                })
                .catch(error => {
                    this.loading = false
                    console.log(error)
                })
            }
        }
    }
</script>
查看更多
放我归山
3楼-- · 2020-04-07 08:30

There are a few good methods of handling async data in Vue.

  1. Call a method that fetches the data in the created lifecycle hook that assigns it to a data property. This means that your component has a method for fetching the data and a data property for storing it.

  2. Dispatch a Vuex action that fetches the data. The component has a computed property that gets the data from Vuex. This means that the function for fetching the data is in Vuex and your component has a computed property for accessing it.

In this case, it looks like your component needs to have a RolledMetal and based on that it retrieves a product. To solve this you can add methods that fetch both of them, and call them on the created lifecycle. The second method should be called in a then-block after the first one to ensure it works as expected.

查看更多
登录 后发表回答