Nuxt3点击下拉按钮获取子菜单API数据及状态显示问题求助
解决方案
你的问题核心在于useLazyFetch返回的data和pending是方法内部的局部变量,模板无法访问,同时缺少“仅请求一次”的限制逻辑。以下是修正后的完整代码,完全满足你的需求:
<template> <NuxtLink :to="url"> {{ label }} <span @click.prevent="getChildren()">▾</span> </NuxtLink> <!-- Submenu --> <div v-if="isExpanded"> <!-- 加载状态显示等待图标 --> <div v-if="pending">⏳ 加载中...</div> <!-- 渲染子菜单列表 --> <div v-else-if="subMenuItems.length"> <div v-for="item in subMenuItems" :key="item.id">{{ item.label }}</div> </div> <!-- 无数据提示 --> <div v-else>暂无子菜单</div> </div> </template> <script setup> const props = defineProps({ label: String, url: String, }); // 控制菜单展开/收起 const isExpanded = ref(false); // 存储子菜单数据(模板可直接访问) const subMenuItems = ref([]); // 标记请求加载状态 const pending = ref(false); // 标记是否已请求过数据,避免重复调用API const hasFetched = ref(false); const handleExpand = () => { isExpanded.value = !isExpanded.value; }; const getChildren = async () => { handleExpand(); // 已请求过数据则直接返回 if (hasFetched.value) return; pending.value = true; try { // 发起API请求 const { data } = await useLazyFetch('/api/items', { server: false, }); // 将返回数据赋值给全局响应式变量 subMenuItems.value = data.value || []; } catch (err) { console.error('获取子菜单失败:', err); subMenuItems.value = []; } finally { pending.value = false; hasFetched.value = true; } }; </script>
关键修改说明:
- 顶层声明响应式变量:把
subMenuItems、pending、hasFetched放在<script setup>顶层,确保模板能直接访问这些变量。 - 避免重复请求:用
hasFetched标记是否已获取数据,点击按钮时先判断状态,已获取则不再调用API。 - 手动维护加载状态:通过
pending变量控制等待图标的显示,让用户清晰感知加载过程。 - 异常处理:添加
try/catch捕获请求错误,避免页面崩溃,同时保证数据状态的一致性。
如果你想直接使用Nuxt自带的请求状态管理,也可以简化成以下写法:
<script setup> // ...其他变量不变 // 初始化时不自动发起请求 const { data: fetchedSubMenu, pending: fetchPending, refresh } = useLazyFetch('/api/items', { server: false, immediate: false, }); const getChildren = async () => { handleExpand(); if (hasFetched.value) return; // 手动触发请求 await refresh(); subMenuItems.value = fetchedSubMenu.value || []; hasFetched.value = true; }; </script>
这种方式直接复用Nuxt返回的pending状态,无需手动维护加载变量,逻辑更简洁,可根据个人习惯选择。
内容的提问来源于stack exchange,提问作者Neatpixels
相关产品推荐
相关产品推荐

