使用Vue @submit指令时FormData对象为空的问题排查
Vue @submit 触发时FormData获取为空的原因与解决办法
问题场景
开发Vue表单时,使用@submit指令处理提交事件,尝试通过FormData获取表单数据时得到空内容,但改用原生form.addEventListener('submit')却能正常获取数据。
核心原因
你在Vue实例挂载前通过document.querySelector('#test-form')获取的表单元素,是初始DOM中的旧节点。Vue挂载到#app-main时,会将挂载目标内部的DOM编译为模板,生成新的DOM树替换原内容,旧的表单元素会被移除。此时用旧节点创建FormData,自然拿不到用户输入的内容。
而原生事件监听如果是在Vue挂载后获取表单元素并绑定,会指向当前活跃的新DOM节点,因此能正常获取数据。
解决方案
方案1:通过事件对象获取当前表单元素
在Vue的提交处理函数中,直接使用事件对象的target属性获取当前表单元素,这是最简单的方法:
const app = Vue.createApp({ name: 'test app', methods: { test(e) { e.preventDefault() // 用e.target获取当前触发事件的表单元素 const formData = new FormData(e.target) for (const [key, value] of formData.entries()) { console.log(`${key}: ${value}`) } } } }).mount('#app-main')
方案2:在Vue挂载后获取表单元素
利用Vue的mounted钩子,在组件挂载完成后再获取表单元素:
const app = Vue.createApp({ name: 'test app', mounted() { this.formElement = document.querySelector('#test-form') }, methods: { test(e) { e.preventDefault() const formData = new FormData(this.formElement) for (const [key, value] of formData.entries()) { console.log(`${key}: ${value}`) } } } }).mount('#app-main')
方案3:使用Vue的ref引用表单元素(推荐)
这是最符合Vue开发风格的方式,通过ref直接获取Vue管理的DOM元素:
const app = Vue.createApp({ name: 'test app', setup() { const formRef = Vue.ref(null) const test = (e) => { e.preventDefault() const formData = new FormData(formRef.value) for (const [key, value] of formData.entries()) { console.log(`${key}: ${value}`) } } return { formRef, test } } }).mount('#app-main')
对应的HTML修改为:
<form @submit="test" ref="formRef"> <input type="text" name="foo"> <button type="submit">submit</button> </form>
总结
这不是Vuev-on指令的Bug,而是DOM节点生命周期的问题——你误用了Vue挂载前的旧DOM元素。通过上述三种方案,都能正确获取表单数据。
内容的提问来源于stack exchange,提问作者dbzx10299
相关产品推荐
相关产品推荐

