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

Vue3如何复用Home.vue的请求数据至AllJobs.vue?无需重复请求

小型Vue项目复用请求数据的简便方案

不用Pinia的话,有几个轻量方案可以实现数据复用,避免重复请求:

方案1:独立API模块+缓存(最推荐)

把请求逻辑抽成单独的工具模块,用变量缓存请求结果,所有组件都调用这个模块的方法,自动复用缓存数据。

步骤1:创建API工具文件

在src/utils/jobApi.js中编写:

// 缓存请求到的岗位数据
let cachedJobs = null;

export async function fetchJobs() {
  // 有缓存直接返回
  if (cachedJobs) {
    return cachedJobs;
  }
  try {
    const res = await fetch("http://localhost:3000/jobs");
    const data = await res.json();
    // 缓存数据
    cachedJobs = data;
    return data;
  } catch (err) {
    console.error(err.message);
    throw err; // 抛出错误让调用组件处理
  }
}

步骤2:修改Home.vue调用API

<template>
  <div class="cards-container">
    <div v-for="job in jobs.reverse().slice(0, 5)" :key="job.id" class="">
      <JobComponent :position="job.position" :department="job.department" :location="job.location"/>
    </div>
  </div>
</template>

<script>
import JobComponent from '../components/JobComponent.vue'
import { fetchJobs } from '../utils/jobApi.js'

export default {
  name: 'Home',
  components: { JobComponent },
  data() {
    return {
      jobs: [],
    }
  },
  async mounted() {
    this.jobs = await fetchJobs();
  }
}
</script>

步骤3:修改AllJobs.vue调用API并渲染

<template>
  <div class="cards-container">
    <div v-for="job in jobs" :key="job.id" class="">
      <JobComponent :position="job.position" :department="job.department" :location="job.location"/>
    </div>
  </div>
</template>

<script>
import JobComponent from '../../components/JobComponent.vue'
import { fetchJobs } from '../../utils/jobApi.js'

export default {
  name: "AllJobs",
  components: { JobComponent },
  data() {
    return {
      jobs: []
    }
  },
  async mounted() {
    this.jobs = await fetchJobs();
  }
}
</script>

方案2:Vue全局属性共享数据

通过Vue的全局属性挂载缓存对象,让所有组件都能访问。

步骤1:在main.js挂载全局缓存

import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App);
// 全局挂载岗位数据缓存
app.config.globalProperties.$jobCache = { jobs: null };

app.mount('#app');

步骤2:修改Home.vue存入缓存

<script>
import JobComponent from '../components/JobComponent.vue'

export default {
  name: 'Home',
  components: { JobComponent },
  data() {
    return {
      jobs: [],
    }
  },
  async mounted() {
    // 没有缓存才请求
    if (!this.$jobCache.jobs) {
      const res = await fetch("http://localhost:3000/jobs");
      this.$jobCache.jobs = await res.json();
    }
    this.jobs = this.$jobCache.jobs.reverse().slice(0, 5);
  }
}
</script>

步骤3:修改AllJobs.vue读取缓存

<template>
  <div class="cards-container">
    <div v-for="job in jobs" :key="job.id" class="">
      <JobComponent :position="job.position" :department="job.department" :location="job.location"/>
    </div>
  </div>
</template>

<script>
import JobComponent from '../../components/JobComponent.vue'

export default {
  name: "AllJobs",
  components: { JobComponent },
  data() {
    return {
      jobs: []
    }
  },
  async mounted() {
    if (this.$jobCache.jobs) {
      this.jobs = this.$jobCache.jobs;
    } else {
      // 若Home还未请求完成,这里发起请求,缓存后其他组件复用
      const res = await fetch("http://localhost:3000/jobs");
      this.$jobCache.jobs = await res.json();
      this.jobs = this.$jobCache.jobs;
    }
  }
}
</script>

方案3:共同父组件统一请求+props传值

如果Home和AllJobs有共同的父组件(比如App.vue),可以把请求逻辑放在父组件,通过props把数据传给两个子组件。

步骤1:修改App.vue统一请求数据

<template>
  <div id="app">
    <!-- 假设Home和AllJobs是App的子组件 -->
    <Home :jobs="jobs" />
    <AllJobs :jobs="jobs" />
  </div>
</template>

<script>
import Home from './components/Home.vue'
import AllJobs from './components/AllJobs.vue'

export default {
  name: 'App',
  components: { Home, AllJobs },
  data() {
    return {
      jobs: []
    }
  },
  async mounted() {
    const res = await fetch("http://localhost:3000/jobs");
    this.jobs = await res.json();
  }
}
</script>

步骤2:修改Home.vue接收props并处理

<template>
  <div class="cards-container">
    <div v-for="job in displayJobs" :key="job.id" class="">
      <JobComponent :position="job.position" :department="job.department" :location="job.location"/>
    </div>
  </div>
</template>

<script>
import JobComponent from '../components/JobComponent.vue'

export default {
  name: 'Home',
  components: { JobComponent },
  props: ['jobs'],
  computed: {
    // 计算前5条数据
    displayJobs() {
      return this.jobs.reverse().slice(0, 5);
    }
  }
}
</script>

步骤3:修改AllJobs.vue接收props并渲染

<template>
  <div class="cards-container">
    <div v-for="job in jobs" :key="job.id" class="">
      <JobComponent :position="job.position" :department="job.department" :location="job.location"/>
    </div>
  </div>
</template>

<script>
import JobComponent from '../../components/JobComponent.vue'

export default {
  name: "AllJobs",
  components: { JobComponent },
  props: ['jobs']
}
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 20:30:52