You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue动态表单附件push触发Maximum call stack栈溢出报错如何解决?

问题修复方案

核心错误原因

  • 你同时为v-file-input绑定了v-model="i.attachments"和@change事件,二者形成了无限触发的死循环:
    1. 选中文件后,v-file-input会首先通过双向绑定自动更新i.attachments的取值
    2. 紧接着触发@change事件,你又手动调用push往同一个attachments数组追加数据
    3. 数组变更触发响应式更新,再次触发组件的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 23:54:00