动态表单项必须用数组存储,不可用对象;v-for需绑定唯一key,字段统一用value/type命名;v-if切换需加响应式key防校验失效;单选/多选应绑定item.value并配置options;删除后须重置对应校验。

动态表单项必须用数组,别用对象存多条数据
你填问卷时点“+新增问题”,背后必须是往数组里 push 一个新对象,而不是给 formData 动态加 question1、question2 这样的属性。Vue 的响应式系统对对象新增属性不敏感,formData.newKey = 'xxx' 不会触发视图更新;而数组的 push、splice 是被 Vue 显式劫持的,能立刻重渲染列表。
常见错误现象:新增一项后输入框没反应、删了第2项结果第3项的数据跑到第2个框里去了——基本都是用了对象当容器,或没给 v-for 配唯一 key。
- 每个动态项必须带唯一
id(推荐用Date.now() + Math.random()拼接,避免时间重复) -
v-for必须绑定:key="item.id",不能用:key="index" - 值字段统一叫
value,类型字段叫type(如'text'、'radio'、'checkbox'),方便后续校验和提交逻辑复用
uni-forms 里 v-if 切换表单项会导致校验失效?加 key 就行
比如问卷中“是否住校”选“是”才显示“宿舍号”字段,用 v-if 控制,但一切换选项,“宿舍号”就校验不触发、甚至清空——这是 uni-forms 组件复用导致的内部状态错乱。
根本原因是:v-if 为 false 时组件被销毁,再为 true 时 Vue 默认尝试复用旧实例,但 uni-forms 的校验注册没重新走一遍。
- 解决方法很简单:给
<uni-forms-item></uni-forms-item>加:key,且 key 要随条件变化,例如:key="'dormInput_' + formData.isDormitory" - 不要用
template包裹再套v-if,那样只是隐藏了 DOM,uni-forms-item依然在注册校验规则,反而可能引发冲突 - 如果字段类型复杂(比如嵌套选择器),key 建议包含类型标识,如
:key="'field_' + item.id + '_' + item.type"
单选/多选题的 value 怎么设计才好绑定和提交
别把选项值硬编码进组件里,也别让每个 radio 单独绑一个变量。动态问卷里,选项是接口返回的,必须可配置、可映射。
正确做法是:每个题目对象里存 options: [{value: 'A', label: '同意'}, {value: 'B', label: '不同意'}],然后用 v-model 绑定到该题的 value 字段上。
- 单选题直接用
<radio-group v-model="item.value"></radio-group>,内部<radio></radio>的对应 options 里的 value - 多选题用
<checkbox-group v-model="item.value"></checkbox-group>,此时item.value必须是数组(初始化写成[],不是''或null) - 提交前校验时,只需检查
item.value是否为空(单选)或长度是否为 0(多选),不用关心具体选项文本
删除中间某一项时,怎么避免数据错位或校验残留
用户删了第3道题,结果第4题的校验提示还挂在第3个位置上——这通常是因为你用了 index 当 key,或者用 splice(index, 1) 后没重置表单校验状态。
uni-forms 的校验规则是按 name 字段注册的,动态项的 name 必须带唯一标识,不能全写成 "answer"。
- 每道题的
<uni-forms-item></uni-forms-item>的name应为"questions[" + index + "].value"或更稳妥的"questions_" + item.id - 删除时用
this.formData.questions.splice(this.formData.questions.findIndex(q => q.id === targetId), 1),别依赖 index - 删完立刻调用
this.$refs.form.resetFields(['questions_' + targetId])清除校验缓存(需给<uni-forms></uni-forms>加ref="form")
最易被忽略的是:没给每个动态题目的 name 做唯一性处理,导致多个项共用一个校验路径,删一个,校验状态全乱。

















