Vue动态表单附件push触发Maximum call stack栈溢出报错如何解决?
问题修复方案
核心错误原因
- 你同时为
v-file-input绑定了v-model="i.attachments"和@change事件,二者形成了无限触发的死循环:- 选中文件后,
v-file-input会首先通过双向绑定自动更新i.attachments的取值 - 紧接着触发
@change事件,你又手动调用push往同一个attachments数组追加数据 - 数组变更触发响应式更新,再次触发组件的
change事件,循环往复直到调用栈溢出
- 选中文件后,
- 附加问题:
v-for使用数组索引k作为key,动态增删行时会出现表单项状态错位的问题。
具体修复步骤
1. 移除冗余的手动push逻辑
Vuetify的v-file-input在multiple模式下,v-model会自动把所有选中的文件存入绑定的数组,完全不需要手动在change事件中做push操作。如果不需要额外处理选中的文件,你可以直接删掉onAttachmentSelected方法和@change事件绑定;如果需要做文件校验等额外操作,修改方法如下:
onAttachmentSelected(e, k) { // e即为当前选中的所有文件数组,不需要push,直接做校验等操作即可 // 示例:校验单个文件不超过10M const overSizeFile = e.find(file => file.size > 10 * 1024 * 1024) if (overSizeFile) { alert('单个附件大小不能超过10M') this.formList[k].attachments = [] return } }
2. 优化v-for的key值(强烈建议)
给每个子表单项添加唯一ID作为key,避免增删行时状态错乱:
// 修改新增行方法,生成唯一ID addNewPO(e) { this.formList.push({ id: Date.now() + Math.random(), // 也可以用uuid库生成更规范的唯一ID co: "", attachments: [], }); }
模板中修改v-for的key绑定:
<v-row v-for="(i, k) in formList" :key="i.id">
3. 提交数据适配
附件无法直接存入MySQL,你需要先把表单数据组装为FormData格式传给后端,后端接收后将文件存储到服务器/对象存储服务,仅把文件访问路径存入MySQL即可,save方法参考:
async save() { const submitForm = new FormData() this.formList.forEach((item, idx) => { submitForm.append(`formList[${idx}].co`, item.co) item.attachments.forEach(file => { submitForm.append(`formList[${idx}].attachments`, file) }) }) await axios.post('你的后端接口地址', submitForm, { headers: { 'Content-Type': 'multipart/form-data' } }) }
内容的提问来源于stack exchange,提问作者Mohamed Raza
相关产品推荐
相关产品推荐

