必须用数组存题并为v-for绑定唯一item.id作为key,禁用index;单选v-model绑定字符串、多选绑定数组且显式checked;v-if切换字段时需加响应式key重置校验。

直接用数组存题、用 v-for 渲染、每项带唯一 id,否则新增/删除后数据错位、输入无响应——这是最常踩的坑,不是逻辑写错了,是数据结构没对。
动态题目必须用数组,别用对象存多条数据
用户点“+新增问题”,背后必须是往 questions 数组里 push 一个新对象,而不是给 formData 动态加 question1、question2 这样的属性。Vue 的响应式系统对对象新增属性不敏感:formData.newKey = 'xxx' 不会触发视图更新;而数组的 push、splice 是被 Vue 显式劫持的,能立刻重渲染列表。
常见错误现象:
- 新增一项后输入框没反应
- 删了第 2 项,结果第 3 项的数据跑到第 2 个框里去了
根本原因基本就是用了对象当容器,或没给 v-for 配唯一 key。
v-for 必须绑定 :key="item.id",不能用 :key="index"
每个动态题目的对象必须带唯一 id(推荐用 Date.now() + Math.random() 拼接,避免时间重复),然后在模板中写成:<uni-forms-item v-for="item in questions" :key="item.id"></uni-forms-item>。
用 index 当 key 看似省事,但一旦插入、删除或排序,Vue 会复用旧 DOM 节点,导致表单值和 UI 错配——比如你删掉中间一项,后面所有项的 value 会集体前移,但输入框内容还留在原地。
单选/多选题的 v-model 怎么绑才不出错
单选题统一用 <radio-group v-model="item.value"></radio-group>,内部 <radio></radio> 的 :value 对应 item.options 里的 value 字段;多选题用 <checkbox-group v-model="item.value"></checkbox-group>,此时 item.value 必须初始化为 [](不是 '' 或 null)。
关键细节:
-
item.value类型要和选项value一致(推荐字符串或数字,别用对象) - 初始值设为
''(单选)或[](多选),微信小程序对undefined回显不友好 - 多选题必须显式写
:checked="item.value.includes(option.value)",否则切换后 UI 不同步
v-if 切换字段时校验失效?加响应式 key 就行
比如“是否住校”选“是”才显示“宿舍号”,用 v-if="formData.isDormitory" 控制,但一切换,字段就清空或校验不触发——这是因为 uni-forms-item 组件销毁后复用,内部校验状态没重置。
解决方法很简单:给 <uni-forms-item></uni-forms-item> 加 :key,且 key 要随条件变化,例如::key="'dormInput_' + formData.isDormitory"。
注意别用 <template v-if></template> 包裹再套 uni-forms-item,那样只是隐藏 DOM,校验规则还在注册,反而可能冲突。
真正难的不是写完功能,而是当题目类型混着来(文本+单选+多选+下拉)、支持增删、还要过校验、最后还能提交——这时候每道题的 id、type、value 字段命名是否统一,v-for 的 key 是否稳定,v-if 的响应式 key 是否包含足够上下文,就全暴露出来了。


















