步骤进度条加载状态怎么同步到每个步骤?
我在做一个多步骤表单,想在每个步骤按钮上显示加载状态,但不知道怎么把 loading 状态精准绑定到当前进行的步骤。
试过用一个变量 currentStepLoading 控制,但切换步骤时状态会错乱。比如第二步提交时,第一步的图标也转起来了……
现在结构大概是这样:
<div v-for="(step, index) in steps" :key="index">
<button>
{{ step.name }}
<Spinner v-if="isLoading && currentStep === index" />
</button>
</div>
但实际 currentStep 更新后,loading 动画还是会在上一步残留一下,体验很怪。有没有更稳妥的做法?
你现在的做法是用一个全局 isLoading 加上 currentStep 来判断,但问题在于:currentStep 变化和 isLoading 变化不是原子操作,Vue 更新 DOM 也是异步的,中间就会有个短暂的"空档期",导致你看到的残留现象。
更稳妥的做法是给每个步骤单独管理自己的 loading 状态,像这样:
先改数据结构,把 loading 状态放到每个步骤对象里:
模板部分改成直接读取对应步骤的 loading:
提交逻辑也很简单,只操作当前步骤的状态:
为什么这样更稳?
第一,每个步骤的 loading 状态是独立的,互不干扰,不存在"全局状态一变带动一片"的问题。
第二,finally 块里统一重置状态,不管接口成功还是失败,都不会留下残留的 loading。
第三,模板里的判断从
isLoading && currentStep === index变成step.loading,逻辑更清晰,也不用在脑子里转两道弯。这里需要注意的是,如果你的 steps 数据是从接口获取的或者其他地方来的,记得在初始化的时候给每个对象加上 loading: false 这个属性,不然会报 undefined。
还有个细节,button 加上 :disabled="step.loading" 可以防止用户手抖连续点击,这个根据你实际需求决定加不加。