Vue的AutoComplete组件输入后下拉列表无法自动聚焦怎么办?
大家好,我在用Vue写AutoComplete组件时遇到个怪问题。当用户输入”ne”后,虽然下拉列表显示了结果,但焦点没有自动定位到第一个选项。我试过在input事件里用querySelector获取第一个li元素调用focus(),但控制台报错”Cannot read property ‘focus’ of null”。
<template>
<div>
<input v-model="query" @input="handleInput">
<ul v-if="results.length">
<li v-for="(item, index) in results" :key="index">{{ item }}</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
query: '',
results: []
}
},
methods: {
handleInput() {
// 模拟异步搜索
setTimeout(() => {
this.results = ['Neil', 'Nemo', 'Nancy']
document.querySelector('.suggestion li:first-child')?.focus()
}, 200)
}
}
}
</script>
后来发现是DOM还没渲染完成就执行了聚焦操作,但改用nextTick包裹后还是不行。有人知道正确的自动聚焦实现方式吗?
先改模板部分,把tabindex加上去,顺便给ul加个类名方便选择:
然后在脚本里这样写:
这里有几个点要注意:第一是tabindex必须加上,不然li默认不是可聚焦元素;第二是$nextTick确实能等DOM更新完,但你还得判断一下元素是不是真的存在,防止意外情况;第三是querySelector的选择器要准确,我这边用了.suggestions li:first-child,比你原来的更明确。
说实话这种问题挺常见的,尤其是涉及到异步和DOM操作的时候,建议以后遇到类似问题可以先打个断点看看元素到底渲染出来没有,能省不少时间。