代码之家  ›  专栏  ›  技术社区  ›  Pablo Araya

Vue JS在渲染前等待数据

  •  1
  • Pablo Araya  · 技术社区  · 6 年前

    我正在做的是进行一些axios调用(一个接一个)。我的问题是,数据是在调用完成之前呈现的,因此视图没有显示任何内容。

    我看到一些代码执行一些“等待”和“异步调用”,但似乎没有什么能解决我的问题。

    这里也有类似的东西 Get component to wait for asynchronous data before rendering 但这也不起作用

    这是我的密码:

        <template>
         <div class="m-portlet m-portlet--full-height" m-portlet="true" id="m_portlet_validate_agenda">
        ...
        <div class="m-portlet__body">
            <div class="tab-content">
                <div class="tab-pane active" id="m_widget2_tab1_diagnose">
                    <div class="m-widget2">
                        <div v-for="diagnose in diagnoses" v-if="diagnoses.length" :class="'m-widget2__item m-widget2__item--' + diagnose.delayColor[0]">
                            <div class="m-widget2__checkbox" >
                                <label class="m-checkbox m-checkbox--solid m-checkbox--single m-checkbox--brand">
                                    <span class="m--bg-white" v-html="diagnose.concurrence"></span>
                                </label>
                            </div>
                            <div class="m-widget2__agenda col-2">
                                {{ diagnose.started_at | moment("HH:mm A") }}
                            </div>
                            <div class="m-widget2__desc" v-if="!isFetching">
                                <div>
                                    <span class="m-widget2__text">
    
                                    </span><br>
                                    <span class="m-widget2__user-name">
                                        <a href="#" class="m-widget2__link m-link">
                                        Paciente: 
                                        {{ diagnose.details[0].name }}
                                        </a><br>
                                        <a href="#" class="m-widget2__link m-link">
                                        Tratante: 
    
                                        </a>
                                    </span>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
             </div>
           </div>
         </div>
        </template>
    
        <script>
        export default {
    
            data() {
                return {
                    events: [],
                    diagnoses: [],
                    urgencies: [],
                    treatments: [],
                    isFetching: true
                }
            },
    
            mounted() {
                this.loadData();
            },
    
            methods: {
    
                loadData: async function() {
                    await axios.get('/pacientes/request-json/agenda/validarAsistencia/eventos').then(res => {
                        this.events = res.data;
                        this.diagnoses = [];
                        this.urgencies = [];
                        this.treatments = [];
                        this.getDetails();
                        this.getDelayColor();
                        this.getConcurrence();
                        vm.$nextTick(function () {
                            $('[data-toggle="m-tooltip"]').tooltip();
                        });
                        console.log('end LoadData');
                    });
                },
    
                getDetails: function() {
                    console.log('cargando');
                    this.events.forEach(event => {
                        axios.get('/pacientes/request-json/agenda/validarAsistencia/eventos/' + event.id).then(res => {
                            event.details = res.data;
                            console.log(res.data);
                        });
                    });
                    this.distributeEvents();
                    console.log('montado');
                },    
    
                distributeEvents: function() {
                    this.events.forEach(event => {
                        if ( event.event.event_type == "diagnosis" )
                        {
                            this.diagnoses.push(event);
                        }
                        else if ( event.event.event_type == "urgency" )
                        {
                            this.urgencies.push(event);
                        }    
                        else if ( event.event.event_type == "treatment" )
                        {
                            this.treatments.push(event);
                        }
                    });
                    this.isFetching = false;
                },
    
                getDelayColor: function() {
                    this.events.forEach(event => {
                        do something...
                    });
                },
    
                getConcurrence: function() {
                    this.events.forEach(event => {                    
                        do something...
                    });
                },
    
                diffMinutes: function(started_at) {
                    do something...
                }
    
            }
    
        }
    
    3 回复  |  直到 4 年前
        1
  •  22
  •   Adi Darachi    6 年前

    要防止在数据返回之前呈现组件,可以:

    1. 向数据添加“isFetching”属性并将其设置为“true”

    3.将v-if=“!isFetching”添加到组件的包装中

        2
  •  4
  •   nicoramirezdev    6 年前

    你没有正确地处理承诺,所以他们不断得到你的信任 悬而未决 . 你可以用 async await ,虽然我更喜欢用普通的 Promise Objects :

    getDetails() forEach 你正在发送一个循环 axios 许诺 每人返回 在数组中调用,然后调用 .

        getDetails: function() {
            let url = '/pacientes/request-json/agenda/validarAsistencia/eventos/';
            console.log('loading');
            let promisedEvents = [];
    
            this.events.forEach(event => {
                promisedEvents.push(axios.get(url + event.id))
            });
    
            return Promise.all(promisedEvents)
        },
    

    在那之后,我会这样做:

        loadData: function() {
            axios.get('/pacientes/request-json/agenda/validarAsistencia/eventos')
                .then(res => {
                    this.events = res.data;
                    this.getDelayColor() // sync operation; no need to be returned
                    return this.getDetails(); // Return the promise(s)
                })
                .then((res) => {
                    // do something with the response from your array of Promises
                })
                .then(anotherPromise) // You can also return a promise like this 
                .catch(handleError) // Very important to handle your error!!
            });
        },
    

        3
  •  1
  •   Pablo Araya    6 年前

    解决方案:

    谢谢你们!

             loadData: function() {
                axios.get('/pacientes/request-json/agenda/validarAsistencia/eventos')
                    .then(res => {
                        this.events = res.data;
                        this.getDelayColor() // sync operation; no need to be returned
                        this.getConcurrence();
                        vm.$nextTick(function () {
                            $('[data-toggle="m-tooltip"]').tooltip();
                        });
                        return this.getDetails(); // Return the promise(s)
                    })
                    .then((res) => {
                        console.log(res.length);
                        for (var i = 0; i < res.length; i++) {
                            this.events[i].details = res[i].data;
                        }
                        this.distributeEvents();
                        console.log('end LoadData');
                    })
                    .catch(error => {
                        console.log('error');
                    })
            },
    
            getDetails: function() {
                let url = '/pacientes/request-json/agenda/validarAsistencia/eventos/';
                let promisedEvents = [];
    
                this.events.forEach(event => {
                    promisedEvents.push(axios.get(url + event.id))
                });
    
                return Promise.all(promisedEvents)
            },
    
    推荐文章