面试题答案
一键面试- 使用
tabindex
属性:- 对于那些默认不参与键盘导航的元素(如自定义的下拉菜单触发按钮等非标准可聚焦元素),可以通过
v - bind:tabindex
指令为其设置合适的tabindex
值。例如,对于一个自定义的下拉菜单触发按钮,设置tabindex="0"
使其可以通过Tab
键获得焦点。在模板中可以这样写:
<button v - bind:tabindex="0" @click="toggleDropdown">Toggle Dropdown</button>
- 对于那些默认不参与键盘导航的元素(如自定义的下拉菜单触发按钮等非标准可聚焦元素),可以通过
- 键盘事件绑定:
keydown
事件:- 在组件内,可以使用
v - on:keydown
(简写为@keydown
)来监听键盘按下事件。例如,对于一个具有多个输入框的表单组件,当用户在一个输入框中按下Tab
键时,我们可以控制焦点的转移,避免焦点跳出组件范围(如果需要的话)。
<template> <div> <input type="text" @keydown="handleKeydown"> <input type="text" @keydown="handleKeydown"> </div> </template> <script> export default { methods: { handleKeydown(event) { if (event.key === 'Tab') { // 这里可以实现自定义的焦点转移逻辑 // 例如:阻止默认的焦点转移,手动将焦点设置到下一个元素 event.preventDefault(); const currentIndex = Array.from(this.$el.querySelectorAll('input')).indexOf(event.target); const nextInput = this.$el.querySelectorAll('input')[currentIndex + 1]; if (nextInput) { nextInput.focus(); } } } } }; </script>
- 在组件内,可以使用
keyup
事件:- 有时候也需要监听
keyup
事件,例如在处理输入框内容的同时,用户可能按下Enter
键提交表单。可以通过@keyup.enter
来监听Enter
键释放事件。
<input type="text" @keyup.enter="submitForm">
- 有时候也需要监听
- 可访问性语义化标签:
- 使用正确的HTML语义化标签,如
button
标签用于按钮,input
标签用于输入框等。Vue组件模板应遵循这些语义,这样浏览器和屏幕阅读器等辅助技术能够正确识别组件内的交互元素。例如:
<template> <div> <button>Click Me</button> <input type="text" placeholder="Enter text"> </div> </template>
- 使用正确的HTML语义化标签,如
- 管理焦点状态:
- 在组件的
data
中定义变量来跟踪当前焦点的元素。例如:
<template> <div> <button @focus="setFocus('button1')" @blur="removeFocus('button1')">Button 1</button> <input @focus="setFocus('input1')" @blur="removeFocus('input1')" type="text"> </div> </template> <script> export default { data() { return { focusedElement: null }; }, methods: { setFocus(elementId) { this.focusedElement = elementId; }, removeFocus(elementId) { if (this.focusedElement === elementId) { this.focusedElement = null; } } } }; </script>
- 然后可以根据
focusedElement
的值来应用一些样式,如添加一个is - focused
类,以便为获得焦点的元素提供视觉反馈,符合可访问性要求。
- 在组件的
.is - focused { outline: 2px solid blue; }
5. **处理下拉菜单等复杂组件**:
- 对于下拉菜单,当使用键盘打开(例如通过`Enter`或`Space`键)后,需要能够使用箭头键在菜单项之间导航。
- 监听`keydown`事件,当按下箭头键时,判断当前菜单项的索引并移动焦点到相应的下一个或上一个菜单项。
```html
<template>
<div>
<button @click="toggleDropdown" @keydown.enter="toggleDropdown" @keydown.space="toggleDropdown">Toggle Dropdown</button>
<div v - if="isDropdownOpen" @keydown="handleDropdownKeydown">
<a href="#" v - for="(item, index) in dropdownItems" :key="index" @keydown.enter="selectItem(index)" @focus="setDropdownFocus(index)">{{item}}</a>
</div>
</div>
</template>
<script>
export default {
data() {
return {
isDropdownOpen: false,
dropdownItems: ['Item 1', 'Item 2', 'Item 3'],
dropdownFocusIndex: 0
};
},
methods: {
toggleDropdown() {
this.isDropdownOpen =!this.isDropdownOpen;
},
handleDropdownKeydown(event) {
if (event.key === 'ArrowUp') {
if (this.dropdownFocusIndex > 0) {
this.dropdownFocusIndex--;
this.$el.querySelectorAll('a')[this.dropdownFocusIndex].focus();
}
} else if (event.key === 'ArrowDown') {
if (this.dropdownFocusIndex < this.dropdownItems.length - 1) {
this.dropdownFocusIndex++;
this.$el.querySelectorAll('a')[this.dropdownFocusIndex].focus();
}
}
},
selectItem(index) {
// 处理菜单项选择逻辑
console.log('Selected item:', this.dropdownItems[index]);
this.isDropdownOpen = false;
},
setDropdownFocus(index) {
this.dropdownFocusIndex = index;
}
}
};
</script>