Vue.js子组件向父组件emit FormData后数据变字符串的解决方法
问题原因
子组件生成的FormData本身无异常,传递后变为字符串的问题,基本是父组件接收逻辑的隐式类型转换、事件监听配置错误导致的。
排查解决步骤
- 第一步:显式验证事件接收内容
不要依赖v-model、内联赋值的简写逻辑,先写独立的事件处理函数,直接校验接收到的payload类型,确认emit传递本身是否正常:<!-- 父组件模板 --> <ChildComponent @input="handleChildPayload" />// 父组件方法 handleChildPayload(payload) { // 打印类型判断,不要直接打印对象本身 console.log('接收到的内容类型:', Object.prototype.toString.call(payload)) // 只有输出 [object FormData] 才说明emit传递逻辑是正常的 } - 第二步:排查赋值阶段的隐式类型转换
如果上一步打印出接收到的是正常FormData,但赋值后变成字符串,检查以下三类问题:- 不要误把自定义emit的payload当成原生事件对象,不要写
@input="parentFormData = $event.target.value"这类针对原生input事件的取值逻辑,自定义事件的$event就是你传递的FormData实例,没有target属性 - 不要对FormData做字符串拼接操作,比如
this.parentData = '前缀' + formData、this.parentData += formData,这类操作会自动把对象转成[object FormData]字符串 - 存储FormData的变量初始值不要设为空字符串,直接初始化为null:
data() { return { // 错误写法:parentFormData: '' parentFormData: null } }
- 不要误把自定义emit的payload当成原生事件对象,不要写
- 第三步:规避响应式系统对特殊内置对象的处理问题
如果上述步骤都正常还是出现类型异常,可把FormData挂载到非响应式属性上(Vue2默认不会对_开头的属性做响应式代理),避免响应式包装对内置对象的影响:handleChildPayload(payload) { // 直接挂载到非响应式属性 this._uploadFormData = payload // 后续上传接口直接使用 this._uploadFormData 即可 } - 额外注意点
不要用JSON.stringify序列化FormData,该操作会得到空对象;如果是Vue3项目,建议不要用input作为自定义事件名,避免和原生事件、v-model默认行为混淆,可改成更语义化的事件名比如update:uploadFormData。
内容的提问来源于stack exchange,提问作者Osman Rafi
相关产品推荐
相关产品推荐

