You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Vue页面在fetch请求加载完数据后再完成渲染加载

现有代码优化点

你当前的写法存在一处可优化的逻辑:两个请求为串行执行,fetchCollections 完成后才会发起 fetchItems,会拉长总请求耗时,建议使用 Promise.all 并行发起两个请求提升效率。

解决方案

1. 实现数据加载完成后再渲染页面

新增加载状态变量控制页面渲染时机,所有数据拉取完成后才渲染页面内容,从根源避免内容跳变问题:

<template>
  <!-- 根容器用v-if控制,加载完成前不渲染内容 -->
  <div v-if="isPageLoaded">
    <!-- 原有页面内容 -->
    <div v-for="item in collections" :key="item.id">{{ item.name }}</div>
    <div v-for="item in items" :key="item.id">{{ item.name }}</div>
    <div id="about">关于我们</div>
  </div>
  <!-- 可加全局 loading 提升体验 -->
  <div v-else>页面加载中...</div>
</template>

<script>
export default {
  data() {
    return {
      collections: [],
      items: [],
      isPageLoaded: false // 新增加载状态
    }
  },
  methods: {
    async fetchCollections() {
      // 先判断有没有缓存数据,有就直接返回,解决数据复用问题
      const cachedCollections = localStorage.getItem('collections')
      if (cachedCollections) return JSON.parse(cachedCollections)
      const res = await fetch('http://localhost:4000/collections')
      const data = await res.json()
      localStorage.setItem('collections', JSON.stringify(data))
      return data
    },
    async fetchItems() {
      const cachedItems = localStorage.getItem('items')
      if (cachedItems) return JSON.parse(cachedItems)
      const res = await fetch('http://localhost:4000/items')
      const data = await res.json()
      localStorage.setItem('items', JSON.stringify(data))
      return data
    }
  },
  async created() {
    // 并行发起两个请求,总耗时等于最慢的那个请求的耗时
    const [collections, items] = await Promise.all([
      this.fetchCollections(),
      this.fetchItems()
    ])
    this.collections = collections
    this.items = items
    // 所有数据准备完成后再设置加载状态为true,触发页面渲染
    this.isPageLoaded = true
  }
}
</script>

2. 路由重加载出错问题优化

如果使用Vue Router,还可以配合路由导航守卫beforeRouteEnter在进入页面前就完成数据拉取,完全避免页面加载过程:

async beforeRouteEnter(to, from, next) {
  const [collections, items] = await Promise.all([
    fetch('http://localhost:4000/collections').then(res => res.json()),
    fetch('http://localhost:4000/items').then(res => res.json())
  ])
  next(vm => {
    vm.collections = collections
    vm.items = items
    vm.isPageLoaded = true
  })
}

3. 锚点失效问题

上述方案已经可以直接解决锚点偏移问题:页面首次渲染时商品模块的高度已经根据动态数据计算完成,#about区块的初始位置就是最终位置,不会出现后续下移的情况,无需适配骨架屏。


内容的提问来源于stack exchange,提问作者Nash Anderson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 09:06:05