最近一直和这个组件打交道, 有多个地方不太完美, 一开始领导让先这么用着, 后期再优化. 最近把几个不完美的地方优化了下. 写下此篇. 让遇到此问题的朋友少走类似的弯路.
先简单说下问题, 这个组件默认是点击option, 下拉框就隐藏. 但当我们开启了触发方式为hover的时候, 也就是expandTrigger: 'hover' 的时候. 这个时候点击option就不会隐藏, 毕竟组件没那么智能, 这时候需要自己手动处理隐藏.我公司目前的做法是无论点击一级二级option都隐藏.毕竟触发已经改成了hover.这个逻辑是没问题的.具体隐藏下拉框的方法是:
this.$refs.cascaderDom.dropDownVisible = false;
当然你要在cascader上加上 ref='cascaderDom'
我们输出下访问到的这个dom对象, 一看你就知道了.
dropDownVisible就是控制下拉框的显隐啦; true为显示, false为隐藏;
ok, 这个问题解决后, 还有个更棘手的问题.就是开启hover后鼠标在一级菜单上下hover触发的时候, 如果某一级菜单没有二级菜单分类, 那么需要隐藏掉二级菜单. 但是官方是默认不隐藏的. 这样体验就不要. 所以还是需要改动.总之就是hover触发一级菜单的时候 , 如果此时有二级菜单那么就显示二级菜单, 否则就隐藏二级菜单. 得益于领导的指导, 也算成功实现了.具体的方法如下:
在mounted的时候 先获取el-cascader-node元素集合. 然后循环给每个option加商onmouseenter事件. 事件内进行判断, 如果此时有二级菜单就获取el-cascader-menu元素集合.设置display: none; 否则就是display: block;
先上代码吧:
// 给cascader绑定鼠标 移入移除事件 实现hover无二级菜单时隐藏二级菜单
cascaderBoundEvent() {
let cascaderNodes = document.querySelectorAll('.el-cascader-node');
for (let i = 0; i < cascaderNodes.length; i++) {
cascaderNodes[i].onmouseenter = (e) => {
this.mouseenterSubcat(cascaderNodes[i]);
}
}
},
// option鼠标移入事件
mouseenterSubcat(node) {
// 获取一级菜单的三角符号 如果有 证明存在二级菜单 否则无二级菜单
let isChildrenNode = node.querySelector('.el-icon-arrow-right');
// 一级下拉框和二级下拉框集合
let cascaderMenus = document.querySelectorAll('.el-cascader-menu');
if (isChildrenNode) {
// 二级下拉框出现
cascaderMenus[1].style.display = 'block';
} else {
cascaderMenus[1].style.display = 'none';
}
},
这种方式虽然比较偏门儿, 但好在是实现了需求. 其实我个人的意愿一直不太主张这种偏门的实现方式. 因为你不知道它会又给你带来什么bug. 这里有一个注意的点就是. 如果你的list是请求回来的. 需要注意渲染完成才可获取到元素集合.
需要说明的一个地方就是怎么判断它有没有二级菜单呢? 我用的是获取el-icon-arrow-right元素的方法.
上图中的三角小符号就是el-icon-arrow-right元素. 它是el-cascader-node的子元素. 也就是说每次mouseenter的时候, 获取到当前el-cascader-node元素, 这个元素就是每一个一级option. 然后再获取当前option下的小三角. 如果此时有小三角. 就让el-cascader-menu元素集合的第一项显示, 否则就隐藏.
这里有两个点需要注意:
1. 有的朋友可能二级菜单为空也显示小三角.这个时候你需要把一级带单的children设为空字符串; 不能是空数组;
2. 此种方法只适用于最多有二级菜单的项目. 假设你的项目有三级或者更多菜单. 那需要进行更多的判断来达到需求.
总结:
从实现需求的角度看, 确实是实现了, 用的也没问题.但我的个人意愿还是尽量不要走这种偏门的路线. 比如在elementui里使用定位去达到你的样式功能需求. 虽然当时是实现了. 但以后偶尔可能会发生的bug你找了半天没找到原因后才发现是当时修改了element组件的某个样式导致的.
有任何都可留言, 看到都会回复的.