vue父子组件处理异步操作

emit("toolbarClick", name) 触发的事件可能会调用一个接口,在接口返回后再关闭 itemLoading。由于 emit 触发的自定义事件返回值通常不会是 Promise,实际异步操作应该在监听该事件的组件里处理。下面给出两种不同场景下的解决方案。

场景一:在当前组件处理异步操作

若异步操作在当前组件里处理,可将异步操作封装成 Promise 并返回,确保 toolbarResultPromise 对象。

xml 复制代码
PageContent.vue
Apply
<script setup>
// ... 已有代码 ...

// 操作栏
function handleToolbar(name) {
  switch (name) {
    // ... 已有代码 ...
    default:
      itemLoading[name] = true; // 开始加载
      // 自定义事件处理函数返回 Promise
      const toolbarResult = new Promise((resolve) => {
        const result = emit("toolbarClick", name, resolve);
        // 如果 emit 返回的本身就是 Promise,直接使用
        if (isPromise(result)) {
          result.then(resolve).catch(resolve);
        }
      });

      if (isPromise(toolbarResult)) {
        toolbarResult.finally(() => {
          itemLoading[name] = false; // 结束加载
        });
      } else {
        itemLoading[name] = false; // 非 Promise 直接结束加载
      }
      break;
  }
}

// ... 已有代码 ...
</script>

场景二:在父组件处理异步操作

若异步操作在父组件处理,可在父组件监听 toolbarClick 事件时,通过传入的回调函数告知当前组件操作完成。

当前组件(PageContent.vue)

xml 复制代码
PageContent.vue
Apply
<script setup>
// ... 已有代码 ...

// 操作栏
function handleToolbar(name) {
  switch (name) {
    // ... 已有代码 ...
    default:
      itemLoading[name] = true; // 开始加载
      emit("toolbarClick", name, () => {
        itemLoading[name] = false; // 结束加载
      });
      break;
  }
}

// ... 已有代码 ...
</script>

父组件示例

xml 复制代码
vue
Apply
<template>
  <PageContent @toolbarClick="handleToolbarClick" />
</template>

<script setup>
import PageContent from './PageContent.vue';

// 处理 toolbarClick 事件
const handleToolbarClick = async (name, done) => {
  try {
    // 模拟异步接口调用
    await new Promise((resolve) => setTimeout(resolve, 2000));
    console.log(`接口调用完成: ${name}`);
  } catch (error) {
    console.error('接口调用出错:', error);
  } finally {
    // 调用 done 函数告知子组件操作完成
    done(); 
  }
};
</script>

总结如下:

  • 场景一:把异步操作封装成 Promise,确保 toolbarResultPromise 对象,在 finally 里关闭加载状态。
  • 场景二:在父组件监听事件时,通过传入的回调函数告知子组件操作完成,从而关闭加载状态。

若异步操作在当前组件处理,推荐场景一;若在父组件处理,推荐场景二。

相关推荐
AI视觉网奇1 小时前
rknn yolo11 推理
前端·人工智能·python
gplitems1231 小时前
Gunslinger – Gun Store & Hunting WordPress Theme: A Responsible
开发语言·前端·javascript
wyzqhhhh4 小时前
less和sass
前端·less·sass
Nan_Shu_6145 小时前
学习:uniapp全栈微信小程序vue3后台-额外/精彩报错篇
前端·学习·微信小程序·小程序·uni-app·notepad++
excel6 小时前
Vue3 中的双向链表依赖管理详解与示例
前端
前端小白从0开始7 小时前
Chrome DevTools高级用法:性能面板内存泄漏排查
前端·chrome·chrome devtools
EveryPossible7 小时前
带有渐变光晕
前端·javascript·css
jojo是只猫7 小时前
Vue 3 开发的 HLS 视频流播放组件+异常处理
前端·javascript·vue.js
卓码软件测评8 小时前
第三方软件登记测试机构:【软件登记测试机构HTML5测试技术】
前端·功能测试·测试工具·html·测试用例·html5
CS Beginner8 小时前
【html】canvas实现一个时钟
前端·html