Vue3 使用Element plus中的el-cascader组件时,点选选项控制台报错:Blocked aria-hidden on an element because its descendant retained focus. The focus must not be hidden from assistive technology users. Avoid using aria-hidden on a focused element or its ancestor. Consider using the inert attribute instead, which will also prevent focus. For more details, see the aria-hidden section of the WAI-ARIA specification at Accessible Rich Internet Applications (WAI-ARIA) 1.3.
Element with focus: <li.el-cascader-node is-active#cascader-menu-2096-2-2>
Ancestor with aria-hidden: <div.el-cascader__dropdown el-popper is-light is-pure el-zoom-in-top-leave-from el-zoom-in-top-leave-active#el-popper-5632>
这个错误虽然不影响正常使用,但是看到控制台有错误,估计咱们程序员都是无法忍受的。参考了很多大佬文章,终于找到终级解决办法:
解决办法:
在main.js添加指令removeAriaHidden
import { createApp } from 'vue'
const app = createApp(App)
// 全局注册移除 aria-hidden 属性的自定义指令
app.directive('remove-aria-hidden', {
mounted (el) {
// 使用 MutationObserver 监听 DOM 变化
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
// 处理添加的节点
if (mutation.addedNodes && mutation.addedNodes.length > 0) {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === Node.ELEMENT_NODE) {
// 处理级联选择器下拉面板
if (node.classList && node.classList.contains('el-cascader__dropdown')) {
node.removeAttribute('aria-hidden')
const hiddenNodes = node.querySelectorAll('.el-cascader-node[aria-hidden="true"]')
hiddenNodes.forEach(n => n.removeAttribute('aria-hidden'))
}
// 处理级联选择器节点
if (node.classList && node.classList.contains('el-cascader-node') && node.hasAttribute('aria-hidden')) {
node.removeAttribute('aria-hidden')
}
// 处理后代节点
const hiddenDescendants = node.querySelectorAll('[aria-hidden="true"]')
hiddenDescendants.forEach(descendant => {
if (descendant.classList.contains('el-cascader-node')) {
descendant.removeAttribute('aria-hidden')
}
})
}
})
}
// 处理属性变化
if (mutation.type === 'attributes' && mutation.attributeName === 'aria-hidden') {
const target = mutation.target
if (target.classList && (
target.classList.contains('el-cascader__dropdown') ||
target.classList.contains('el-cascader-node')
)) {
target.removeAttribute('aria-hidden')
}
}
})
})
// 开始观察整个文档
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['aria-hidden']
})
// 初始处理
const dropdowns = document.querySelectorAll('.el-cascader__dropdown[aria-hidden="true"]')
dropdowns.forEach(dropdown => dropdown.removeAttribute('aria-hidden'))
const nodes = document.querySelectorAll('.el-cascader-node[aria-hidden="true"]')
nodes.forEach(node => node.removeAttribute('aria-hidden'))
}
})
在组件中使用自定义指令
// ...
<el-row>
<el-col>
<span>选择商品分类:</span>
<div v-remove-aria-hidden class="cascader-container">
<el-cascader
placeholder="请选择"
v-model="selectedOptions"
:options="options"
:props="cascaderProps"
@change="handleChange"
clearable
ref="cascaderRef"
/>
</div>
</el-col>
</el-row>
// ...
在修改onMounted钩子,手动处理可以存在的aria-hidden属性
onMounted(() => {
// 组件挂载后,手动处理一次可能存在的 aria-hidden 属性
setTimeout(() => {
const dropdowns = document.querySelectorAll('.el-cascader__dropdown[aria-hidden="true"]');
dropdowns.forEach(dropdown => dropdown.removeAttribute('aria-hidden'));
const nodes = document.querySelectorAll('.el-cascader-node[aria-hidden="true"]');
nodes.forEach(node => node.removeAttribute('aria-hidden'));
}, 500);
})
在setup中添加对级联选择器引用
setup () {
const cascaderRef = ref(null) // 添加对级联选择器的引用
return {
cascaderRef // 添加对级联选择器引用的返回
}
}
更新css样式,确保级联选择器的可选择性
<style lang="less" scoped>
.el-alert {
margin-bottom: 10px;
}
.cascader-container {
display: inline-block;
}
/* 添加以下CSS来处理aria-hidden问题 */
:deep(.el-cascader-dropdown) {
.el-cascader-node[aria-hidden="true"] {
display: none;
}
/* 确保下拉面板是可见的 */
&[aria-hidden="true"] {
display: block !important;
visibility: visible !important;
}
}
</style>
到此完美解决,干净的控制台让人心情更舒坦!
PS:只注册自定义组件也可以修复,求稳我还是全部都要了,觉得对您有帮助,点个赞支持一下,谢谢。