页面意外刷新的根源是form默认提交行为,而非emit事件本身;需在事件处理函数开头调用event.preventdefault()阻止,默认回车或button点击会触发表单提交导致重载。

页面意外刷新跟“Emit 事件”本身无关,真正触发刷新的是 HTML form 元素的原生提交行为。所谓“Emit 事件导致刷新”,其实是开发中常见的一种误解——你监听了某个自定义事件(比如 Vue 中的 emit('submit')),但忘了阻止外层 <form></form> 的默认动作,结果表单照常提交,页面就刷了。
根本原因:浏览器对 form 的硬性规则
无论你用的是原生 HTML、Vue 的 <el-form></el-form>,还是 React 的受控表单,只要 DOM 中存在一个未加防护的 <form></form> 标签,它就自带两个“自动触发机制”:
- 点击
<button></button>且没写type="button"→ 默认当type="submit"处理 - 在表单内只有一个文本类输入框(如
<input type="text">、<el-input></el-input>)时按回车 → 自动触发表单提交
这两种操作都会让浏览器向 action 地址发请求(若没设 action,就向当前 URL 发 GET 请求),页面随之重载——验证提示一闪而过、数据清空、状态丢失,全因这个默认行为没被拦住。
必须写的那一行代码:preventDefault()
阻止刷新最直接、最可靠的方式,就是在处理函数开头调用 event.preventDefault()。它不依赖框架,不挑绑定方式,且必须放在异步操作(如 fetch 或 emit)之前:
- 原生 JS:
form.addEventListener('submit', e => { e.preventDefault(); /* 后续逻辑 */ }) - Vue 模板:
<form></form>(.prevent就是preventDefault()的语法糖) - Vue + Element:
<el-form></el-form>(Vue 2 需.native;Vue 3 可省略)
别再依赖 return false
return false 在现代事件绑定中基本失效:
- 仅在内联写法(如
<form onsubmit="return myFn()"></form>)中起作用 - 用
addEventListener或onsubmit = fn赋值时,return false只是函数返回值,不会影响事件流 - 它还可能意外阻止事件冒泡,带来其他副作用
所以,统一用 event.preventDefault(),清晰、可控、无歧义。
配合 emit 的正确姿势
如果你在子组件里用 emit('submit') 通知父组件提交,那父组件接收时仍要负责拦截原生行为:
- 子组件(含表单结构):
<form> <button>发送</button> </form> - 父组件:
<childcomponent></childcomponent>,其中handleFormSubmit是纯业务逻辑,不再涉及form.submit()
这样,表单控制权完全交由 Vue 逻辑接管,不再和浏览器默认行为纠缠。










