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

VueJS中如何实现仅在API初始加载完成后才触发Watcher?

问题根因

你当前的实现存在三个核心问题:

  • 初始请求返回后给user赋值时,深度监听器会被立即触发,直接修改了isLoaded状态
  • 深度监听对象时,handler的oldVal和newVal是同一个引用,oldVal != newVal的判断永远生效
  • 计算属性isDisabled的逻辑和需求相反:需求是用户修改后禁用按钮,原逻辑是isLoaded为true时按钮禁用,和预期不符

解决方案

新增一个初始化状态位,跳过初始数据填充阶段的监听触发,调整相关逻辑即可实现需求,修改后完整代码如下:

<template>
  <div id="app">
    <input type="text" v-model="user.userId" /> <br />
    <br />
    <input type="text" v-model="user.title" /> <br />
    <br />
    <button :disabled="isDisabled">Update</button>
  </div>
</template>

<script>
export default {
  name: "App",
  watch: {
    user: {
      handler() {
        // 仅当初始化完成后,用户修改才触发状态变更
        if (!this.isInitializing) {
          this.isFormModified = true;
        }
      },
      deep: true,
    },
  },
  computed: {
    isDisabled() {
      // 表单被用户修改后禁用按钮
      return this.isFormModified;
    },
  },
  async created() {
    const response = await fetch("https://jsonplaceholder.typicode.com/todos/1");
    const json = await response.json();
    this.user = json;
    // 初始数据赋值完成后,再关闭初始化状态,开启监听
    this.isInitializing = false;
  },
  data() {
    return {
      user: {
        userId: 0,
        id: 0,
        title: "",
        completed: false,
      },
      // 初始化状态标记,初始为true表示处于数据填充阶段
      isInitializing: true,
      // 表单是否被用户修改的标记
      isFormModified: false,
    };
  },
};
</script>

改动说明

  • 新增isInitializing状态位:初始为true,标识当前处于初始数据填充阶段,此阶段的user变更不会触发禁用逻辑
  • 新增isFormModified状态位:专门用来标记表单是否被用户修改,语义更清晰
  • 调整监听器逻辑:仅当isInitializing为false时,才会将isFormModified设为true
  • 修正计算属性逻辑:直接返回isFormModified,用户修改后按钮自动禁用
  • 优化异步请求写法:改用async/await的标准写法,避免嵌套回调

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 09:06:10