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 里关闭加载状态。
  • 场景二:在父组件监听事件时,通过传入的回调函数告知子组件操作完成,从而关闭加载状态。

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

相关推荐
kyriewen10 小时前
Anthropic 估值逼近万亿美元,Claude Sonnet 5 + Claude Science 一天两连发
前端·ai编程·claude
小徐_233312 小时前
Wot UI 2.2.0 发布:Button 新增 subtle,VideoPreview 预览体验继续增强
前端·微信小程序·uni-app
天蓝色的鱼鱼14 小时前
关于 CSS 你可能不知道的属性,但关键时刻很有用
前端·css
泯泷15 小时前
第 2 篇:设计第一套字节码:Opcode、Instruction 与 Constant Pool
前端·javascript·安全
妙码生花15 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(十五):优化细节、网络请求封装
前端·后端·ai编程
泯泷15 小时前
第 1 篇:从 1 + 2 开始:亲手写出第一台 JSVM
前端·javascript·安全
团团崽_七分甜15 小时前
Spring Boot 核心知识点总结
前端
lichenyang45315 小时前
从一个按钮开始,理解 ASCF 框架到底在做什么
前端
古夕15 小时前
第三方 SSO 接入实践:redirect_uri 编码、回调一致性与跨项目联调
前端·vue.js