问题描述
elementUi的el-select下拉选择框,打开之后除非失去焦点或者获取到对应dom关闭,不然不会自动关闭.在有滚动条de弹窗中使用时就会出现打开下拉框,滚动弹窗,el-select下拉框超出弹窗范围的问题.
解决方案
- 1 超出隐藏,这个最简单只需要给弹窗设置超出隐藏样式即可.
- 2 获取下拉框dom 主动使其失焦(适合页面中只有一个下拉框的情况)
- 3 给内容区(就是滚动条所在的盒子)加上自定义指令
方法1:只要你们测试接收就没问题,方法2:不适用我这个,在vue中获取dom就需要配合ref属性,但是我页面有很多个下拉框,并且还可以动态添加,方法3:思路就是给父盒子绑定一个自定义指令,根据类名获取到所有的下拉框,监听内容区滚动时将打开的下拉框样式改成关闭.(这是同事之前的方案)
之前自己想的监听内容滚动,然后主动将焦点聚焦到自己写的一个input上,但实践发现,即使聚焦到我写的ipt上,已经打开的下拉框也不会失去焦点,不解~~
自定义指令
简单说一下自定义指令的使用,自定义指令是vue提供的原生方法,下面是一个简单例子,(通过自定义指令让元素颜色等于传入值)
//html部分
//<div v-color="'red'"></div>
//directives和vue中的data同级
directives:{
// 自己起名 在标签上使用 v-xxx 以下对应名 如v-color
color:{
//el绑定元素 binding传入的值 即v-color="xxx" xxx的值
bind(el, binding) {
//让绑定颜色等于传入的值
el.style.color = binding.value
},
inserted(el, binding) {
console.log(el, binding);
},
update(el, binding) {
console.log(el, binding);
},
}
},
directives里包含三个钩子,可以根据自己需求使用
bind
:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。inserted
:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)update
:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
自动关闭下拉的自定义指令
有几个注意事项:
首先el-select标签要加上:popper-append-to-body=‘false’ 下拉框默认是会插入body下面的,也就是不在咱们的弹窗中,如果不在弹窗中,根据类名获取父盒子下的元素,这一步就走不通了
其次一定要找对父盒子,因为自定义是监听父盒子的滚动才会去处理关闭事件
directives:{
closeSelect{
bind(el, binding, vnode) {
//这里el是有滚动条的父盒子
//获取盒子下所有下拉框
let target = el.getElementsByClassName('el-select-dropdown')
//处理方法 让所有下拉框隐藏
el.handler = () => {
for (let item of target) {
item.style.display = 'none'
}
}
//监听父子滚动
el.addEventListener('scroll', el.handler)
}
}
}
最后 把v-closeSelect加在对应标签上就可以了