3

tree提供的方法貌似没有可以直接获取节点DOM,或者点击勾选节点响应函数参数node其实只是传入data的数据对象,拿不到DOM,得想想法子来获取之


事情是这样的:最近做一个表单,要能勾选一个二级的下拉数据,于是就想起了element的tree组件,而且二级的数据是要调用接口懒加载展开的,这个应该很多人会遇到这种需求,tree组件即支持勾选框又支持懒加载节点,功能是够用的。

所以起初我是这样用组件的:

<el-tree
:data="exitDataOnlyFirst"
:props="{label: 'name'}"
:load="loadNode"
node-key="code"
:expand-on-click-node="true"
:default-checked-keys="form.checkedKeysSecond"
lazy
ref="dataTree"
show-checkbox>
</el-tree>

注: 我的展示数据大概样子如下:

data = [
{code: 1, name: '一', children: [{code: 11, name:'11'}]}
]

不过,在做编辑修改的时候,遇到这个组件就有点小困难了,虽然它有支持默认勾选节点的属性配置default-checked-keys,不过问题页面第一次加载这个组件的时候,一般来说我只加载第一级的数据,不加载第二级,尽管只要checked-keys设置的匹配,点击第一级展开之后,第二级只要一匹配上就会自动勾选,但显然这多一步的操作无疑不符合正常交互流程也不是很好体验,那只能考虑更直观点的操作了,那就是要能默认展开已经被选的第一级数据下的第二级数据,并勾选上相关节点。

expand-on-click-node一般支持除勾选框外的节点部分点击后展开子节点。

现在要优化的几个点是:

  1. 勾选未展开子节点的一级节点时,能够同时展开二级节点,并勾选上所有
  2. 组件初始化展示data数据时,能展开已经被勾选过的二级节点

针对第一点,其实只要解决勾选一级节点触发展开子节点即可,勾选所有,组件已经实现了的,但上面我也提到过了expand-on-click-node一般支持除勾选框外的节点部分点击才会触发展开,勾选框只负责勾选功能,那怎么让它也触发展开呢,这个时候就需要用到@check-change响应了,

<el-tree
:data="exitDataOnlyFirst"
:props="{label: 'name'}"
:load="loadNode"
node-key="code"
:expand-on-click-node="true"
:default-checked-keys="form.checkedKeysSecond"
lazy
@check-change="treeCheck"
ref="dataTree"
show-checkbox>
</el-tree>

响应函数这么写:

treeCheck(currentData, isCheck) {
    //if (currentData.leaf) return
    if (!currentData.children.length  &&  isCheck) {
        // 点击这个data对应的节点的展开图标
        const  currentCode  =  currentData.code
        const  $current  = Array.from(this.$refs.dataTree.$children).filter($child  => {return  $child.node.data.code  ===  currentCode
    })[0]
        $current.$el.childNodes[0].childNodes[0].click()
    }
}

利用第二个参数isCheck获悉到勾选节点是将其选中,同时该节点还没有children,可作为还未展开过的依据,此时要是check-chage能提供当前节点的dom或者有展开功能函数提供就好了,然而并没有,和同事交流的时候还说要修改源码,有点大费周章的感觉,不过好在查看了整个tree的ref,发现$childrens这个属性,进而发现其node.data刚好是传入的data对象对应的数据,因此,可以利用数据遍历和过滤的方式来一步一步找到对应的dom,只要找到 展开箭头 的图标dom,再手动click一下,就解决了~

有了第一点获取节点dom和对应展开图标dom的经验后,第二点就很好做了,正如一早提到的default-checked-keys告知了组件只要有出现这些key就勾选上,于是第二点的方案就可以定位到 解决展开那些有被勾选中子节点的一级节点上,然后通过遍历和匹配数据获取对应的dom,在手动click展开图标即可,剩下的加载操作,让组件帮你完成。

总结一下tree的几个关键属性:

  1. data: 初始化时传入作为第一级节点数据
  2. load: 懒加载触发的函数,和lazy搭配
  3. expand-on-click: 点击节点触发展开或者收起子节点
  4. default-checked-keys: 告诉组件要默认勾选中的节点的key数组
  5. check-change: 节点选中状态发生变化时的回调
  6. show-checkbox: 显示节点勾选框
  7. ref: 用来获取tree组件的实例和dom

当发现组件api不够用的时候,只要想法设法完成功能,需要用到dom的时候,还需要多多观察。


Dont
7k 声望144 粉丝

学如逆水行舟不进则退