Vue路由切换时input的autofocus失效 如何实现自动聚焦
解决方案
原生autofocus属性仅在页面首次加载时生效,单页应用路由切换本质是组件的卸载与重新挂载,不会触发整页重载,因此原生属性不会重新执行,可通过以下几种方案实现需求:
方案1:通过ref手动触发聚焦(单组件快速实现)
给目标输入框绑定ref,在组件挂载完成的生命周期钩子中主动调用输入框的focus()方法,以Login.vue为例:
<template> <form> <!-- 移除原生autofocus,绑定ref --> <input type="text" ref="accountInput" /> <RouterLink to="/register">Register now!</RouterLink> </form> </template>
Vue3 组合式API对应脚本逻辑:
<script setup> import { ref, onMounted, nextTick } from 'vue' const accountInput = ref(null) onMounted(() => { // 若组件使用了路由过渡动画,需包裹nextTick等DOM更新完成后再执行 nextTick(() => { accountInput.value?.focus() }) }) </script>
Vue2/选项式API对应脚本逻辑:
<script> export default { mounted() { this.$nextTick(() => { this.$refs.accountInput?.focus() }) } } </script>
Register.vue按照相同逻辑修改即可。
方案2:自定义v-focus指令(全局复用最优解)
如果项目中有多处需要自动聚焦的输入框,可注册全局自定义指令,一次配置后所有组件直接调用即可,无需重复编写ref和生命周期逻辑。
在项目入口文件(通常为main.js)中注册指令:
// Vue3 注册写法 import { createApp } from 'vue' import App from './App.vue' const app = createApp(App) app.directive('focus', { mounted(el) { el.focus() } }) app.mount('#app')
// Vue2 注册写法 import Vue from 'vue' Vue.directive('focus', { inserted(el) { el.focus() } })
注册完成后,所有组件中直接在需要自动聚焦的输入框上加v-focus即可,替换原生的autofocus属性:
<input type="text" v-focus />
补充说明
如果输入框被包裹在KeepAlive缓存组件中,除了挂载钩子外,还需要在onActivated(Vue3)/activated(Vue2)钩子中再次触发focus逻辑,避免缓存切回时焦点丢失。
内容的提问来源于stack exchange,提问作者Mishen Thakshana
相关产品推荐
相关产品推荐

