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
相关产品推荐
相关产品推荐

