You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3函数执行期间DOM未实时更新问题及解决过程

Vue DOM更新阻塞问题排查与解决

我编写了一个切换状态变量的函数作为实际逻辑的占位实现,遇到的问题是Vue在函数执行完成前不会更新DOM,尝试使用nextTick也无效。

模板代码

<div>
  <q-icon v-if="status === 'DONE'" name="mdi-check-circle" color="green" size="2em"/>
  <q-icon v-if="status === 'PENDING'" name="mdi-checkbox-blank-circle-outline" color="orange-8" size="2em"/>  
  <q-icon v-if="status === 'FAILED'" name="mdi-alert-circle" color="red-8" class="q-pr-sm" size="2em"/> 
  <q-spinner-pie  v-if="status === 'PROCESSING'" color="primary" size="2em" class="q-pr-sm" /> 
  <span class="text-italic text-caption" >( {{ curTotal }} / {{ itemTotal }} )</span>
</div>

初始实现与问题

最初的函数实现中使用了自定义的sleep函数模拟耗时操作:

processImages(){  
    this.status = 'PROCESSING'
    for ( let i = 0; i < this.itemTotal; i++){
        this.sleep(1000)
        this.curTotal += 1
    }
}

sleep(miliseconds) {
    var currentTime = new Date().getTime();
    while (currentTime + miliseconds >= new Date().getTime()) {
    }
}

执行后发现status切换为PROCESSING的状态图标和curTotal的更新都不会实时展示,直到整个函数执行完成后才一次性更新DOM。

问题根源

上述sleep函数通过同步while循环阻塞主线程,JavaScript是单线程模型,主线程被阻塞时,Vue的异步DOM更新队列根本没有机会执行,导致所有DOM更新被推迟到函数执行完毕后才进行,nextTick也无法解决这个问题——因为它只是等待下一次DOM更新周期,但主线程被占着根本轮不到更新周期执行。

修正后的实现

将同步阻塞的sleep替换为异步的API调用(使用async/await)后,DOM更新恢复正常:

async processImages(){  
    this.rows[0].status = 'PROCESSING'
    for ( let i = 0; i < this.itemTotal; i++){
        const { data } = await $fetch('/api/scrape', {
            method: 'GET',
        })
        this.rows[0].curTotal += 1
    }
    this.rows[0].created = true
}

await会在API请求期间释放主线程,让Vue的DOM更新队列有机会执行,因此status和curTotal的变化能实时反映到页面上。

内容的提问来源于stack exchange,提问作者Tom T

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 14:20:20