Nuxt动态页面跳转异常:仅搜索_slug页可用的问题
我有一个菜单组件,其中包含跳转到_slug页面的search方法,代码如下(已尽可能简化):
<template> <input @keydown.enter="search" type="text" v-model="term" id="groupId" placeholder="Pesquisar" class="rounded-lg pl-10 bg-[#E6E6E6] text-[#818181] h-7"> </template> <script lang="ts"> export default { name: 'Products', data(): {} { return {}; }, async mounted() { this.get() }, methods: { search() { const searchUrl = `/search/${this.term}`; try { this.$router.push(searchUrl); console.log(this.term); } catch (error) { console.error(error); } console.log(this.term) }, async get() { // 该函数用于查询数据库,与当前问题无关 }, } } </script>
该搜索功能在已处于搜索_slug页面(如http://localhost:3000/search/thingthatisearched)时可正常工作。搜索_slug页面的简化代码如下:
<template> <!-- 展示所有产品 --> </template> <script lang="ts"> export default { name: 'Products', data(): { products: Product[] } { return { products: [] }; }, async mounted() { this.get() }, methods: { async get() { // 查询数据库 }, } } </script>
但在首页等其他页面(首页代码如下),该搜索功能无法正常工作:
<template> <div> <Menu></Menu> <MainBanner></MainBanner> <Products></Products> </div> </template> <script lang="ts"> export default ({ name: 'IndexPage', }) </script>
在非搜索_slug页面执行搜索时,URL会先跳转到http://localhost:3000/search/thingthatisearched,随后瞬间变为http://localhost:3000/?并返回首页,且所有页面中term值都能在控制台正常输出,即使移除其他组件仅保留菜单问题仍存在。请问为何该功能仅在搜索_slug页可用,以及其他页面出现此行为的原因?
核心原因
问题出在输入框的浏览器默认表单提交行为:当输入框未被包裹在<form>标签中时,按下回车会触发浏览器的隐式表单提交,页面会刷新并跳转至当前URL(带?参数),直接覆盖了$router.push的路由跳转动作。
而搜索_slug页面可能因结构特性(比如输入框所在上下文已处理默认行为),阻止了浏览器的默认提交,所以路由跳转能正常执行。
解决办法
方法1:阻止回车事件的默认行为
修改search方法,接收事件参数并调用preventDefault():
search(e: KeyboardEvent) { e.preventDefault(); // 阻止浏览器默认表单提交 const searchUrl = `/search/${this.term}`; try { this.$router.push(searchUrl); console.log(this.term); } catch (error) { console.error(error); } console.log(this.term) }
同时在模板中传递事件对象:
<input @keydown.enter="search($event)" ...>
方法2:用表单包裹输入框并阻止提交
将输入框放入<form>标签,通过@submit.prevent阻止默认提交:
<form @submit.prevent> <input @keydown.enter="search" ...> </form>
验证效果
修改后,在首页按下回车时,浏览器不会触发默认刷新,$router.push的跳转行为会正常生效,不会被页面刷新覆盖。
内容的提问来源于stack exchange,提问作者Pedro Souza

