目标
点击文字可以展开树形结构,并可以获取到最内层项目。
情景
碰到一个需求需要使用树形插件,但iView的树形插件只能点击三角才能展开子项,新版本4.4.0提供的属性expand-node虽然可以点击文字展开,却没有提供可以获取到树最内层项目的事件,研究无果,索性打算拓展,放弃expand-node属性选用select-node属性,利用on-select-change来获得被点击的项目。
实例
组件:
<Tree select-node
@on-select-change='selectNnode'
@click.native = "clickChangeNode"
empty-text=""
:data="TreeDataArray"></Tree>
所传入数据TreeDataArray:
TreeDataArray = [
{
title: "outer1",
expand: false,
children: [
{
title: "inner1",
expand: false,
children:[
{
title: "root1",
expand: false,
},
{
title: "root2",
expand: false,
}
]
}
]
}
]
此时渲染的样式为:
然后为它编写click事件:
clickChangeNode(e: any) {
let parent = e.target.parentNode;
if (!parent) return;
let checkSelector = parent.querySelector('.ivu-tree-arrow');
if (!checkSelector) return;
if (checkSelector.querySelector('i')) {
checkSelector.click();
}
}
这里要做的事其实就是找到节点前的箭头,然后对其进行模拟点击,要注意,根节点的前面没有下箭头,所以要对齐内部做一个查找i标签操作用来区分。
然后通过selectNnode获取数据,对数据进行一个筛选:
TreeSelData = {
};
selectNnode(e: any) {
if (e.length !== 0) {
let isRootChildNode = Object.keys(e[0]).find((e: any) => e === "children");
if (!isRootChildNode) {
this.TreeSelData = e[0];
} else {
this.TreeSelData = {
}
}
}
}
很简单,通过children判定是否为根节点,非空是因为多次点击同一个根节点时防止数据被清空,当发现children存在说明点击了非根节点的节点,此时清除记录的根节点。
稍微修改一下css
.ivu-tree-children{
position: relative;
.ivu-tree-title{
color:#000;
padding:1%;
background:#d6eafe;
border-radius: 0;
width:100%;
text-indent: 20px;
}
.ivu-tree-arrow{
position: absolute;
margin-left:5px;
margin-top:2px;
}
}
现在的效果:
点击root1/root2可以获得根节点了,达成了目标。
完整的vue
<template>
<div>
<Tree @on-select-change='selectNnode' select-node @click.native = "clickChangeNode" empty-text="" :data="TreeDataArray"></Tree>
</div>
</template>
<script lang="ts">
import {
Vue, Component } from "vue-property-decorator";
@Component()
export default class MedicalRecordDetail extends Vue {
TreeDataArray = [
{
title: "outer1",
expand: false,
children: [
{
title: "inner1",
expand: false,
children:[
{
title: "root1",
expand: false,
},
{
title: "root2",
expand: false,
}
]
}
]
}
];
TreeSelData: any = {
};
selectNnode(e: any) {
if (e.length !== 0) {
let isRootChildNode = Object.keys(e[0]).find((e: any) => e === "children");
if (!isRootChildNode) {
this.TreeSelData = e[0];
} else {
this.TreeSelData = {
}
}
}
console.log(this.TreeSelData);
}
clickChangeNode(e: any) {
let parent = e.target.parentNode;
if (!parent) return;
let checkSelector = parent.querySelector('.ivu-tree-arrow');
if (!checkSelector) return;
if (checkSelector.querySelector('i')) {
checkSelector.click();
}
}
}
</script>
<style lang="scss">
.ivu-tree-children{
position: relative;
.ivu-tree-title{
color:#000;
padding:1%;
background:#d6eafe;
border-radius: 0;
width:100%;
text-indent: 20px;
}
.ivu-tree-arrow{
position: absolute;
margin-left:5px;
margin-top:2px;
}
}
</style>