uni-app动态增减表单项需用Vue.set或变异方法确保响应式,避免直接索引赋值;表单嵌套需初始化响应式对象并设唯一key;提交前用$nextTick同步数据;小程序真机异常需控制数组长度、抽离组件、避免大对象。

uni-app 动态增减表单项时 data 数组不更新?
直接改数组下标(如 this.formList[0] = {...})或用 push/splice 操作后视图不刷新,是 uni-app(基于 Vue 2)响应式限制导致的。Vue 2 无法检测直接索引赋值和长度修改,必须用 Vue.set 或数组变异方法。
- ✅ 正确做法:用
this.$set(this.formList, index, newItem)替代this.formList[index] = newItem - ✅ 增加项统一用
this.formList.push(...)或this.formList = [...this.formList, newItem] - ✅ 删除项用
this.formList.splice(index, 1)(splice是 Vue 2 支持的变异方法) - ❌ 避免:
this.formList[index].field = 'xxx'—— 若field是新增属性,需先用this.$set(this.formList[index], 'field', 'xxx')
uni-app 表单嵌套对象数组怎么双向绑定?
模板中用 v-model 绑定 formList[i].name 看似可行,但一旦数组重排、过滤或异步更新,容易丢失响应性或报 Cannot set reactive property on undefined 错误。
- 确保初始化时每个子项都是响应式对象:不要写
formList: []后再push({}),而要用push(this.$data.$options.data().itemTemplate)或显式this.$set(this.formList, i, { name: '', value: '' }) - 模板中避免深层路径硬编码,推荐为每项生成唯一
key:,防止复用导致 v-model 错位 - 如果字段含动态 key(如后端返回
extra_fields),绑定前先用this.$set(item, key, value)初始化,否则v-model无效
uni-app 多层嵌套表单提交前如何校验并收集数据?
用户点“添加”后立即输入、未失焦就提交,v-model 可能还没触发更新;或某项被删掉但校验逻辑仍遍历旧索引,导致 undefined 报错。
- 提交前执行
this.$nextTick(() => { /* 收集 this.formList */ }),确保 DOM 和响应式数据同步 - 校验循环用
for (let i = 0; i 而非for...in,避免遍历到原型方法 - 收集数据时用解构复制,避免引用污染:
const payload = this.formList.map(item => ({ ...item })) - 删除项后建议清空对应 input 的 focus(uni.hideKeyboard()),防止 iOS 下键盘残留导致输入错位
uni-app 动态表单在小程序真机上表现异常?
H5 正常,但微信/支付宝小程序里增减项卡顿、v-model 失效、甚至白屏——常见于未处理小程序 setData 限制或递归深度过大。
- uni-app 的
this.formList过长(>50 项)时,每次变更都触发整段 setData,小程序会拒绝或延迟渲染;建议分页或虚拟滚动(用scroll-view+display: none控制可视区) - 避免在
formList中存大对象(如 base64 图片),应只存 url 或 id,提交时再拼装 - 真机调试开启
uni.setEnableDebug(true),留意控制台是否出现Exceed max data size或setData recursive call - 复杂场景建议把表单项抽成自定义组件,用
props+$emit单向数据流,比纯 data 数组更可控
最易忽略的是:在 onLoad 或 onShow 中直接 this.formList = res.data —— 如果 res.data 是普通数组,没经过响应式包裹,后续所有增减操作都会失效。务必用 this.$set 或重新赋值新数组。










