Svelte子组件如何包装on:click事件并等待父组件异步函数?
解决Svelte按钮组件等待父组件异步任务完成的问题
核心思路是利用Svelte事件派发的特性:dispatch函数会返回一个Promise,它会等待所有绑定到该事件的处理函数(包括异步函数)执行完成。基于这个特性,我们可以在子组件内部控制加载状态,无需父组件感知。
子组件实现(ActionButton.svelte)
<script> import { createEventDispatcher } from 'svelte'; const dispatch = createEventDispatcher(); let isRunning = false; async function handleClick() { isRunning = true; try { // 派发click事件并等待父组件的异步函数执行完毕 await dispatch('click'); } finally { // 无论异步任务成功/失败,都恢复按钮状态 isRunning = false; } } </script> <button on:click|preventDefault={handleClick} disabled={isRunning}> {#if isRunning} <span>加载中...</span> {:else} <slot /> {/if} </button>
父组件使用示例
<script> import ActionButton from './ActionButton.svelte'; async function someAsyncFunction() { // 模拟异步操作,比如API请求 await new Promise(resolve => setTimeout(resolve, 2000)); console.log('异步任务执行完成'); } </script> <ActionButton on:click={someAsyncFunction}> 执行异步任务 </ActionButton>
关键说明
- 子组件内部接管点击事件,先将
isRunning设为true触发加载状态,再通过dispatch('click')调用父组件绑定的异步函数,并用await等待其完成。 finally块确保异步任务无论成功还是失败,按钮都会恢复正常状态,避免出现永久加载的情况。- 父组件无需关心子组件的内部状态,只需像使用普通按钮一样通过
on:click绑定异步函数即可,完全符合需求。
内容的提问来源于stack exchange,提问作者Matthew Moisen
相关产品推荐
相关产品推荐

