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

Vue中重新赋值ref后丢失响应性?原因及解决方法

Vue组件loading状态更新异常问题排查与修复

问题代码

组件代码(简化版)

<template>
  <div @click="loadEvents">{{ loading }}</div>
</template>

<script setup>
import { ref } from 'vue'
let loading = ref(false)

loadEvents()
function loadEvents() {
  const res = backendApi.getEvents(selectedDate.value)
  loading = ref(res.loading)
}
</script>

backendApi.getEvents方法代码

getEvents() {
  const loading = ref(true)
  axios.get(...).then(r => loading.value = false)
  
  return { loading }
}

问题分析

  1. 首次加载正常,点击后无更新:首次调用loadEvents时,组件的loading变量绑定的是初始创建的ref,后端返回的ref变化能通过初始关联同步到DOM。但点击触发loadEvents时,执行loading = ref(res.loading)相当于把组件的loading变量替换成了一个新的ref对象,而模板绑定的还是最初的那个ref,新ref的状态变化无法触发DOM更新。
  2. 赋值loading.value = res.loading.value仅生效一次:这种写法只是把后端loading当前的true值拷贝到组件的loading里,两者没有建立响应式关联。当后端请求完成把loading.value改为false时,组件的loading不会同步更新。

修复方案

方案一:监听后端loading状态同步到组件

通过watch监听后端返回的loading值,实时同步到组件的loading变量:

<template>
  <div @click="loadEvents">{{ loading }}</div>
</template>

<script setup>
import { ref, watch } from 'vue'
let loading = ref(false)

loadEvents()
function loadEvents() {
  const res = backendApi.getEvents(selectedDate.value)
  // 立即同步初始值,并监听后续变化
  watch(res.loading, (newVal) => {
    loading.value = newVal
  }, { immediate: true })
}
</script>

方案二:组件自行管理loading状态(更推荐)

放弃依赖后端返回的ref,组件内部手动控制loading状态,逻辑更清晰:

<template>
  <div @click="loadEvents">{{ loading }}</div>
</template>

<script setup>
import { ref } from 'vue'
let loading = ref(false)

loadEvents()
function loadEvents() {
  loading.value = true
  // 修改后端API,让它返回axios请求的Promise
  backendApi.getEvents(selectedDate.value)
    .then(() => {
      loading.value = false
    })
    .catch(() => {
      loading.value = false // 异常场景也要重置loading
    })
}
</script>

// 对应的backendApi.getEvents修改:
getEvents(date) {
  return axios.get(/* 请求地址和参数 */).then(r => r.data)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 22:25:29