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
相关产品推荐
相关产品推荐

