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

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

相关推荐
Spirited_Away2 分钟前
脚手架开发之多包管理(npm, yarn, pnpm workspaces)
前端·面试
tiantian_cool12 分钟前
Xcode 导入与使用 SVG 文件矢量图适配全流程
前端
小泥巴呀25 分钟前
手写一个简单的vue——响应系统1
前端·vue.js
ze_juejin28 分钟前
插件化和模块化的对比
前端
前端康师傅29 分钟前
网页为什么会白屏?
前端·http·面试
李剑一29 分钟前
Tauri2.0本地实现导入导出,有坑!
前端·vue.js
执行上下文30 分钟前
Element Plus Upload 添加支持拖拽排序~
前端·javascript·element
forever_Mamba30 分钟前
从重复到优雅:前端筛选逻辑的优化之旅
前端·javascript·性能优化
一个小浪吴呀31 分钟前
生死簿应用
前端
好好好明天会更好31 分钟前
vuedraggable-拖拽插件使用小计
前端