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 分钟前
【PPTist】添加PPT模版
前端·学习·编辑器·html
陈王卜4 分钟前
django+boostrap实现发布博客权限控制
java·前端·django
景天科技苑12 分钟前
【vue3+vite】新一代vue脚手架工具vite,助力前端开发更快捷更高效
前端·javascript·vue.js·vite·vue项目·脚手架工具
SameX14 分钟前
HarmonyOS Next 安全生态构建与展望
前端·harmonyos
石小石Orz21 分钟前
Three.js + AI:AI 算法生成 3D 萤火虫飞舞效果~
javascript·人工智能·算法
小行星12523 分钟前
前端预览pdf文件流
前端·javascript·vue.js
join825 分钟前
解决vue-pdf的签章不显示问题
javascript·vue.js·pdf
小行星12530 分钟前
前端把dom页面转为pdf文件下载和弹窗预览
前端·javascript·vue.js·pdf
Lysun00139 分钟前
[less] Operation on an invalid type
前端·vue·less·sass·scss
土豆湿1 小时前
拥抱极简主义前端开发:NoCss.js 引领无 CSS 编程潮流
开发语言·javascript·css