最近在做地图开发的需求时,出现了一个bug:antdv 的树形选择器展开下拉面板时,再点击地图,面板并没有正常收起,而点击其他地方是可以正常收起的。-_-|| 没办法,遇到问题就想办法解决吧
项目环境及版本
技术栈:Vue2(2.6.12)、ES6、Ant Design of Vue(1.7.8)
运行环境:Node(v14.17.6)、Npm(6.14.15)
一、实现步骤
- 绑定 a-tree-select 的 open 属性
在查看 antdv 官方文档时,tree-select 的api介绍相对较少,想起之前做 Element Plus 的时候,有说树形组件下拉是融合了 select 跟 tree 组件的,说不定能有灵感。果然!在 select 组件介绍找到了可以通过设置open
属性来控制面板的显隐。

template代码实现:
html
<a-tree-select :open="areaOpen"
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
class="item-width tree-width"
allowClear
showArrow
multiple
treeCheckable
:maxTagCount="1"
v-model="selectedRegion"
:tree-data="areaTreeData"
:replaceFields="areaFieldNames"
placeholder="区域">
</a-tree-select>
js
data () {
return {
/** 区域选择面板是否打开 */
areaOpen: false,
}
}
-
自定义指令
- 由于检索框有多个树形选择器,所以考虑封装
自定义指令
实现面板收起。 - 参数dropdownEl:下拉面板的类名,通过 dropdownClassName 配置
- 参数openField:绑定的 open 字段名
- 需要在指令修改 data 里的值,需要在 bind (el, binding, vnode) 写上 vnode 参数
- 由于检索框有多个树形选择器,所以考虑封装
js
import Vue from 'vue'
Vue.directive('click-outside', {
bind (el, binding, vnode) {
const vm = vnode.context;
const { dropdownEl, openField } = binding.value;
// 定义事件处理函数,绑定到 el 上方便解绑
el.__clickOutsideHandler__ = function (event) {
const dropdownPanels = document.querySelectorAll(`.${dropdownEl}`);
// 1. 判断是否点击下拉面板
const isClickInsideDropdown = Array.from(dropdownPanels).some(panel => panel.contains(event.target));
if (isClickInsideDropdown) return
// 2. 如果点击目标元素上,切换状态;否则,关闭面板
const isClickOnEl = el.contains(event.target);
vm[openField] = isClickInsideDropdown || isClickOnEl ? !vm[openField] : false;
}
document.addEventListener('click', el.__clickOutsideHandler__);
},
unbind (el) {
// 移除事件监听
document.removeEventListener('click', el.__clickOutsideHandler__);
delete el.__clickOutsideHandler__;
}
});
- 指令的使用
v-
+指令名称
即可使用该指令,参数写在后面。- 一个参数时直接传,多个参数则传一个对象
js
<a-tree-select v-click-outside="{dropdownEl: 'areadropdown', openField: 'areaOpen'}"
dropdownClassName="custom-tree-dropdown-style areadropdown"
>
</a-tree-select>
二、实现效果
没有录屏软件,之后再补个录屏效果吧,下次一定。
主要是点击面板,open不做改变;点击元素则切换面板收起&显示状态;点击元素外则收起面板。没问题 okok
总结
主要绑定open
属性+自定义指令实现,代码写得太漂亮了忍不住分享一下。(✿◡‿◡)
以上就是解决树形组件面板收起问题啦!下班下班,端午快乐-
