Vue表单项赋值后无法输入问题解决

问题背景

  • 打开编辑页Form表单时,从后台接口获取已有数据并赋值到对应的输入框中,并通过v-model对数据进行绑定,会导致输入框输入无效的状态,且无报错信息
    问题分析
  1. Vue可以检测data中属性property的变化,但是不能直接检测数组、对象的变化
  2. 直接存在于data中的property可以检测并响应,但是后续定义并赋值property的无法检测
js 复制代码
// data
return {
  form: {}
}
// methods
getForm(res) {
  this.form = res.data
}

解决方法

  1. 通过forceUpdate强制更新,但是需要每个输入框都加(不推荐
  2. 赋值时通过扩展运算符...将源对象拷贝到目标对象(或者Object.assign等),表单中的控件会保持响应式,可以进行修改(推荐
js 复制代码
this.form = {...res.data}

原理拓展

  1. 为什么不能直接使用=给对象赋值
    • 在 Vue 中使用 v-model 将输入框与 form 对象的属性绑定时,Vue 会在内部为这些属性创建 getter 和 setter。这些 getter 和 setter 负责监听属性的变化并通知 Vue 响应式系统。这样,当输入框的值改变时,Vue 将自动更新相关的视图。
    • 然而,如果直接给 form 对象赋一个新的对象,Vue 就无法检测到对象的属性变化,因为此时 Vue 只是将新对象赋给了原来的引用,而不是修改了对象的属性。这就导致了输入框无法输入的问题,因为 Vue 没有监听到 form 对象的变化。
    • 使用 Object.assign() 或扩展运算符 ... 可以解决这个问题的原因在于它们都是在修改原对象的基础上进行的。虽然它们看起来像是将一个新的对象赋给了 form,但实际上是在原对象的基础上修改了属性。这样做会触发 Vue 的响应式系统,因为 Vue 会检测到属性的变化并更新视图。
  2. 可以使用深拷贝吗,有必要吗?
    • 可以使用深拷贝解决问题
    • 但是深拷贝并不是必要的,因为只需要确保更新对象的属性而不是整个对象。深拷贝会创建一个新的对象,这可能会导致性能开销较大,并且在大型对象上可能会引起不必要的复杂性。
    • 使用深拷贝虽然可以解决问题,但并不是最佳选择。相反,使用浅拷贝方法如 Object.assign() 或扩展运算符能够更有效地实现我们的目标,而且更符合这种情况的需求。
  3. JS直接赋值和浅拷贝的区别
    • 赋值,将一个对象赋值给一个新的对象的时候,赋的其实是该对象在栈中的地址,而不是堆中的数据。也就是一个对象的改变就会改变另外一个对象。
    • 浅拷贝,浅拷贝会创建一个对象,再去遍历原始对象,如果原对象的属性值是基础类型,那么就拷贝基础类型,如果是引用类型,则拷贝的是指针。
相关推荐
加班是不可能的,除非双倍日工资2 小时前
css预编译器实现星空背景图
前端·css·vue3
wyiyiyi2 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
gnip3 小时前
vite和webpack打包结构控制
前端·javascript
excel3 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
阿华的代码王国3 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
一条上岸小咸鱼3 小时前
Kotlin 基本数据类型(三):Booleans、Characters
android·前端·kotlin
Jimmy3 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
草梅友仁3 小时前
草梅 Auth 1.4.0 发布与 ESLint v9 更新 | 2025 年第 33 周草梅周报
vue.js·github·nuxt.js
ZXT4 小时前
promise & async await总结
前端
Jerry说前后端4 小时前
RecyclerView 性能优化:从原理到实践的深度优化方案
android·前端·性能优化