Vue3/Nuxt3路由切换时保持搜索输入框焦点问题求助
解决Nuxt3路由切换后搜索输入框焦点丢失问题
问题分析
你的TopNavBar位于Nuxt3布局中,路由切换时输入框虽短暂获得焦点但随即丢失,核心原因是路由切换过程中Nuxt的页面渲染会触发DOM更新操作,抢占了输入框的焦点;另外你代码中存在script标签内重复编写input模板的语法错误,这也可能导致组件异常。
修复方案
1. 修正代码语法错误
首先删除<script setup>内重复的input标签代码,这是无效且会引发问题的写法。
2. 用nextTick延迟设置焦点
通过nextTick等待路由切换后的DOM更新完全完成,再执行焦点设置,避免被后续渲染操作覆盖:
<template> <input type="search" name="search-library" ref="searchInput" @focus="initSearch" /> </template> <script setup> import { ref, watch, nextTick } from 'vue' const router = useRouter() const route = useRoute() const searchInput = ref(null) function initSearch() { // 注意:路由name是配置中的name字段(如'foo'),不是路径字符串 if (route.name !== 'foo') { router.push({ path: '/foo', query: { initSearch: 'true' }, key: route.fullPath }) } } watch( () => router.currentRoute.value.path, async (newRoute) => { if (newRoute === '/foo' && searchInput.value) { await nextTick() searchInput.value.focus() } } ) </script>
3. 结合query参数精准触发(可选优化)
利用你已有的initSearch查询参数,在路由更新时精准判断并设置焦点,同时可清除参数避免重复触发:
<template> <input type="search" name="search-library" ref="searchInput" @focus="initSearch" /> </template> <script setup> import { ref, watch, nextTick } from 'vue' const router = useRouter() const route = useRoute() const searchInput = ref(null) function initSearch() { if (route.name !== 'foo') { router.push({ path: '/foo', query: { initSearch: 'true' }, key: route.fullPath }) } } watch( () => route.query.initSearch, async (val) => { if (val === 'true' && searchInput.value) { await nextTick() searchInput.value.focus() // 清除query参数,避免刷新页面重复触发 router.replace({ query: { ...route.query, initSearch: undefined } }) } }, { immediate: true } // 页面加载时也检查query参数 ) </script>
关键注意事项
- 路由判断时,
route.name对应路由配置中的name字段(如{ path: '/foo', name: 'foo' }),不要用路径字符串直接对比。 v-focus指令如果是全局生效的,保留即可,但上述方案已通过代码逻辑确保焦点设置,可根据实际情况选择是否保留。
内容的提问来源于stack exchange,提问作者Georg
相关产品推荐
相关产品推荐

