【问题标题】:Get component to wait for asynchronous data before rendering获取组件在渲染前等待异步数据
【发布时间】:2018-09-03 18:11:21
【问题描述】:

我正在调用端点以带回一个对象,该对象确实获取数据,但速度不足以让组件获取数据并呈现。相反,组件在应该有数据的地方呈现空白值。

如果我在创建时中断代码,然后可能一秒钟后继续,文本会正确呈现。

如何实现它直到数据返回才呈现?

我的 API 调用:

checkScenarioType: function () {
    this.$http.get('ScenariosVue/GetScenarioTypeFromParticipant/' + this.ParticipantId).then(response => {
        // get body data
        this.ScenarioType = response.body.value;
        if (this.ScenarioType.timeConstraint) {
            store.commit('switchConstraint');
        }
    }, response => {
        // error callback
    });
}

有问题的组件:

var questionArea = Vue.component('questionarea', {
    props: ["scenariotype"],
    data: function () {
        return ({
            position: "",
            vehicleType: ""
        });
    },
    methods: {
        transformValuesForDisplay: function () {
            switch (this.scenariotype.perspective) {
                case 1: {
                    this.position = "Driver";
                    this.vehicleType = "Autonomous";
                    break;
                }
                case 2: {
                    this.position = "Passenger";
                    this.vehicleType = "Manually Driven";
                    break;
                }
                case 3: {
                    this.position = "Driver";
                    this.vehicleType = "Manually Driven";
                    break;
                }
            }
        }
    },
    beforeMount() {
        this.transformValuesForDisplay();
    },
    template: 
    `<h1>You are the {{ this.position }}! What should the {{ this.vehicleType }} car do?</h1>`
});

【问题讨论】:

    标签: ajax web-services asynchronous vue.js vuejs2


    【解决方案1】:

    在异步加载数据的情况下,我们通常使用简单的v-if 来隐藏元素,直到数据出现。

    模板如下:

    <h1 v-if="position">You are the {{ position }}! What should the {{ vehicleType }} car do?</h1>
    

    注意在模板中使用this 是不必要的。

    此外,在您的情况下,您可以将 (deep/immediate) watch 添加到道具中,而不是 beforeMount() 挂钩,以便在外部加载时获取更改:

      watch: {
        scenariotype: {
          handler: function(newValue) {
                this.transformValuesForDisplay();
          },
          deep: true,
          immediate: true
        }
      },
    

    下面的完整演示。

    Vue.component('questionarea', {
      props: ["scenariotype"],
      data: function () {
        return ({
          position: "",
          vehicleType: ""
        });
      },
      methods: {
        transformValuesForDisplay: function () {
          switch (this.scenariotype.perspective) {
            case 1: {
              this.position = "Driver";
              this.vehicleType = "Autonomous";
              break;
            }
            case 2: {
              this.position = "Passenger";
              this.vehicleType = "Manually Driven";
              break;
            }
            case 3: {
              this.position = "Driver";
              this.vehicleType = "Manually Driven";
              break;
            }
          }
        }
      },
      watch: {
      	scenariotype: {
          handler: function(newValue) {
        		this.transformValuesForDisplay();
          },
          deep: true,
          immediate: true
        }
      },
      template: 
      `<h1 v-if="position">You are the {{ position }}! What should the {{ vehicleType }} car do?</h1>`
    });
    
    new Vue({
      el: '#app',
      data: {
      	ScenarioType: {perspective: null}
      },
      methods: {
        checkScenarioType: function () {
          this.$http.get('https://reqres.in/api/users/2').then(response => {
            // get body data
            this.ScenarioType.perspective = response.body.data.id; // for testing purposes only
          }, response => {
            // error callback
          });
        }
      },
      mounted: function() {
        this.checkScenarioType();
      }
    })
    <script src="https://unpkg.com/vue"></script>
    <script src="https://unpkg.com/vue-resource"></script>
    
    <div id="app">
      <p>Notice while it is null, the h1 is hidden: {{ ScenarioType }}</p>
      <br>
      <questionarea :scenariotype="ScenarioType"></questionarea>
    </div>

    【讨论】:

    • 哇,非常好的答案,非常感谢,这很奏效!
    猜你喜欢
    • 1970-01-01
    • 2022-01-15
    • 2019-07-21
    • 2016-08-02
    • 1970-01-01
    • 1970-01-01
    • 2021-07-12
    • 2019-05-30
    • 2021-12-07
    相关资源
    最近更新 更多