[Vue] 第1385天 使用vue,如何让模板等待接口请求数据完成后再进行页面渲染?

2,873 阅读1分钟

v-if

在Vue中,可以使用 v-if 指令来实现在数据请求完成后再进行页面渲染。 例如,可以在data中定义一个loaded变量来表示数据是否加载完成,然后在模板中使用 v-if 指令来判断该变量是否为 true,只有在数据加载完成后,模板才会进行渲染。

<template>
  <div v-if="loaded">
    <!-- 渲染数据 -->
  </div>
  <div v-else>
    <!-- 加载动画 -->
  </div>
</template>

<script>
export default {
  data() {
    return {
      loaded: false,
      data: null,
    };
  },
  mounted() {
    // 发起数据请求
    fetchData().then((data) => {
      this.data = data;
      this.loaded = true;
    });
  },
};
</script>

在这个例子中,当loadedfalse时,渲染的是一个加载动画,当数据请求完成后,loaded变为true,模板会重新渲染显示数据。 需要注意的是,由于Vue的异步渲染机制,即使数据请求完成后,模板也可能先于数据渲染。因此,如果需要确保数据已经加载完成再进行其他操作,可以使用 $nextTick 方法,确保在下一个DOM更新周期执行操作

this.loaded = true;
this.$nextTick(() => {
    // 在DOM更新之后进行操作
});

函数组件

依赖数据注入后在调用挂载渲染

// index.js
import Vue from 'vue';
import store from '@/store';
import router from '@/router';
import DialogLogisticsInvoice from '@/views/fba/logisticsInvoice/components/TheLogisticsInvoiceDialog/DialogLogisticsInvoice';

const DialogLogisticsInvoiceComponent = Vue.extend(DialogLogisticsInvoice);
let app;
DialogLogisticsInvoice.open = (propsData = {}) => {
  if (!app) {
    app = new DialogLogisticsInvoiceComponent({
      propsData,
      router, // 内部组件依赖在注入
      store, // 内部组件依赖在注入
      watch: {
        $route() {
          this.$emit('destroyDialog');
        }
      }
    });
  }
  // 销毁 实例 DOM
  app.$on('destroyDialog', () => {
    app.$destroy();
    app.$el.remove();
    app = null;
  });
  app.$mount();
  document.body.appendChild(app.$el);
  // 延迟 保留动画效果
  Vue.nextTick(() => {
    app.open();
  });
};

export default DialogLogisticsInvoice;
// 调用者等待数据注入后创建组件
const result = await this.$http.xxxxx()
DialogLogisticsInvoice.open(result)

JSX

v-if原理一样

render() {
    return (
        <div id="tag-list" ref="tagList">
            {showTag.length ? <div></div> : ''}
        </div>
    );
}

扩展阅读

【分享】Dialog业务组件函数式调用

更多题目

github.com/haizlin/fe-…