vue横向树结构_基于vue的树形组织架构树组件(可勾选, 点击选中)

本文展示了如何使用Vue创建一个横向展示的树形组件,该组件支持节点的点击选中和勾选功能。通过自定义组件`my-self-tree`,实现了节点的展开、收起、选中和勾选逻辑,并提供了数据处理方法,如展开状态维护、节点选择和检查状态的更新。示例代码中包含节点的层级遍历和数据结构处理。
摘要由CSDN通过智能技术生成
Document

*{

margin: 0;

padding: 0;

}

li{

list-style: none;

padding: 10px;

}

.arrow{

cursor: pointer;

display: inline-block;

transition: transform .3s;

}

.arrowTransform{

transform: rotate(90deg);

}

.selected{

background: #2b85e4;

}

:tree-data="treeData"

:flat-tree="flatTree">

Vue.component("my-self-tree", {

props: ["treeData", "flatTree"],

data() {

return {

}

},

template: `

  • :class="{arrowTransform: item.expand, arrow: true}"

    @click="handleExpand(item)"

    v-show="item.children && item.children.length">>

    {{item.label}}

    v-show="item.expand"

    :tree-data="item.children"

    :flat-tree="flatTree">

`,

created: function() {

},

methods: {

//展开或收起

handleExpand(item) {

var expand = item.expand,

nodeKey = item.nodeKey;

var node = this.flatTree[nodeKey].node;

this.$set(node, "expand", !expand);

},

//节点选中

handleSelect(item) {

var nodeKey = item.nodeKey;

var node = this.flatTree[nodeKey].node;

var currentSelectedKey = this.flatTree.findIndex(obj => {

return obj.node.selected;

});

//每次只能选择一个

if(currentSelectedKey >= 0 && currentSelectedKey != item.nodeKey) {

this.$set(this.flatTree[currentSelectedKey].node, 'selected', false);

}

this.$set(node, 'selected', !node.selected);

this.getSelectNodes();

},

//节点勾选

handleCheck(item) {

var checked = item.checked,

nodeKey = item.nodeKey;

var node = this.flatTree[nodeKey].node;

this.$set(node, 'checked', checked);

this.updateTreeUp(nodeKey);

this.updateTreeDown(node, { checked: checked});

this.getCheckedNodes();

},

//判断当前勾选节点的父节点是否需要勾选

updateTreeUp(nodeKey) {

var parentKey = this.flatTree[nodeKey].parent;

var childrenKey = "children";

if (typeof parentKey == 'undefined') return;

var node = this.flatTree[nodeKey].node;

var parent = this.flatTree[parentKey].node;

if (node.checked == parent.checked) return;

if (node.checked == true) {

this.$set(parent, 'checked', parent[childrenKey].every(function (node) {

return node.checked;

}));

} else {

this.$set(parent, 'checked', false);

}

this.updateTreeUp(parentKey);

},

//判断当前勾选节点的子节点是否勾选

updateTreeDown(node) {

var changes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

var childrenKey = "children";

for (var key in changes) {

this.$set(node, key, changes[key]);

}

if (node[childrenKey]) {

node[childrenKey].forEach(function (child) {

this.updateTreeDown(child, changes);

}.bind(this));

}

},

//获取已勾选节点

getCheckedNodes() {

var arr = this.flatTree.filter(item => {

return item.node.checked;

}).map(item => {

return item.node;

});

console.log(arr)

},

//获取已选中节点

getSelectNodes() {

var arr = this.flatTree.filter(item => {

return item.node.selected;

}).map(item => {

return item.node;

});

console.log(arr)

}

}

})

new Vue({

el: "#app",

data: {

treeData: [],

flatTree: []

},

created: function() {

//模拟请求数据

setTimeout(() => {

var arr = [

{

label: '一级 1',

children: [

{

label: '二级 1-1',

children: [

{

label: '三级 1-1-1',

}

]

}

]

},

{

label: '一级 2',

children: [

{

label: '二级 2-1',

children: [

{

label: '三级 2-1-1',

}

]

}, {

label: '二级 2-2',

children: [

{

label: '三级 2-2-1',

}

]

}

]

},

{

label: '一级 3',

children: [

{

label: '二级 3-1',

children: [

{

label: '三级 3-1-1',

}

]

},

{

label: '二级 3-2',

children: [

{

label: '三级 3-2-1',

}

]

}

]

}

];

this.treeData = this.compileTreeData(arr);

this.flatTree = this.compileFlatTree(arr);

},2000);

},

methods: {

//数据初始化(添加某些必要属性)

compileTreeData(arr) {

function newAttr(node, parent) {

node.expand = false;//是否展开

node.checked = false;//是否勾选

node.selected = false;//是否选中

if(node.children) {

node.children.forEach(child => {

return newAttr(child, node);

})

}

}

arr.forEach(item => {

newAttr(item);

});

return arr;

},

//编制各节点对应关系

compileFlatTree(arr) {

var keyCounter = 0;

var childrenKey = "children";

var flatTree = [];

function flattenChildren(node, parent) {

node.nodeKey = keyCounter++;

flatTree[node.nodeKey] = {

node: node,

nodeKey: node.nodeKey

};

if (typeof parent != 'undefined') {

flatTree[node.nodeKey].parent = parent.nodeKey;

flatTree[parent.nodeKey][childrenKey].push(node.nodeKey);

}

if (node[childrenKey]) {

flatTree[node.nodeKey][childrenKey] = [];

node[childrenKey].forEach(function (child) {

return flattenChildren(child, node);

});

}

}

arr.forEach(function (rootNode) {

flattenChildren(rootNode);

});

return flatTree;

}

}

})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值