Reputation: 3
I want to make Treeview like this:
A
|--B
| |--BC1
| | |--BC1-S
| | |--BC1-1
| | |--BC1-2
| |__BC2
| |--BC2-S
| |--BC2-1
| |--BC2-2
|--G
|--GC1
|--GC1-S1
| |--GC1-1
| |--GC1-2
|
|--GC1-S2
|--GC1-3
|--GC1-4
I have data came from API like this: (ID, Root, Attribute, Depth)
datas: [
[1, 0, 'A', 0],
[2, 1, 'B', 1],
[3, 2, 'BC1', 2],
[4, 3, 'BC1-S', 3],
[5, 4, 'BC1-1', 4],
[6, 4, 'BC1-2', 4],
[7, 2, 'BC2', 2],
[8, 7, 'BC2-S', 3],
[9, 8, 'BC2-1', 4],
[10, 8, 'BC2-2', 4],
[11, 1, 'G', 1],
[12, 11, 'GC1', 2],
[13, 12, 'GC1-S1',3],
[14, 13, 'GC1-1', 4],
[15, 13, 'GC1-2', 4],
[16, 11, 'GC1-S2',3],
[17, 16, 'GC1-3', 4],
[18, 16, 'GC1-4', 4]
]
Template:
<tr v-for="data in datas" :key="data[0]">
<td>
<div v-if="data[3] == 0" class="tt tt-parent" style="left: 0px;">
<div class="content">{{ data[2] }}</div>
</div>
<div v-else-if="data[3] == 1" class="tt tt-parent" style="left: 47px;">
<div class="tail" style="height: 26px; width: 47px; left: -23.5px;"></div>
<div class="content">{{ data[2] }}</div>
</div>
<div v-else-if="data[3] == 2" class="tt tt-parent" style="left: 95px;">
<div class="tail" style="height: 26px; width: 47px; left: -23.5px;"></div>
<div class="content">{{ data[2] }}</div>
</div>
<div v-else-if="data[3] == 3" class="tt tt-parent" style="left: 143px;">
<div class="tail" style="height: 26px; width: 47px; left: -23.5px;"></div>
<div class="content">{{ data[2] }}</div>
</div>
<div v-else-if="data[6] == 4" class="tt" style="left: 191px;">
<div class="tail" style="height: 26px; width: 47px; left: -23.5px;"></div>
<div class="content">{{ data[2] }}</div>
</div>
</td>
</tr>
CSS:
.tt-table div.tt {
display:inline-block;
position:relative;
}
.tt-table div.tt div.content {
border:1px gray solid;
border-radius: 2px;
z-index: 10;
padding:0 4px 0 5px;
position:relative;
background-color: #dbffbe;
width: 100px;
}
.tt-table div.tt div.tail {
border:2px gray solid;
border-right: 0;
border-top: 0;
position:absolute;
border-radius: 2px;
bottom: 11px;
left: -10px;
z-index: 0;
}
Hi all, I want to create a treeview like this.
This is one of the failed examples:
Upvotes: 0
Views: 647
Reputation: 5075
first you need to structure your data
into parent-child relation (use internal java script function to modify the array data into parent-child object or modify it at server)
then you can use recursive rendering like below.
// modified data from array
var data = {
id: 1,
name: 'A',
open: true, // default open
children: [{
name: 'B',
children: [{
name: 'BC1',
children: [{
name: 'BC1-S',
children: [{
name: 'BC1-1'
},
{
name: 'BC1-2'
}
]
}]
},{
name: 'BC2',
children: [{
name: 'BC2-S',
children: [{
name: 'BC2-1'
},
{
name: 'BC2-2'
}
]
}]
}]
},
{
name: 'G',
children: [{
name: 'GC1',
children: [{
name: 'GC1-S1',
children: [{
name: 'GC1-1'
},
{
name: 'GC1-2'
}
]
},{
name: 'GC1-S2',
children: [{
name: 'GC1-3'
},
{
name: 'GC1-4'
}
]
}]
}]
}
]
}
// define the item component
Vue.component('item', {
template: '#item-template',
props: {
model: Object
},
data: function() {
return {
open: this.model.open
}
},
computed: {
isFolder: function() {
return this.model.children &&
this.model.children.length
}
},
methods: {
toggle: function() {
if (this.isFolder) {
this.open = !this.open
}
}
}
})
new Vue({
el: '#main',
data: {
treeData: data
}
})
body {
font-family: Menlo, Consolas, monospace;
color: #444;
}
.tree-view {}
.tree-view>ul {
padding-left: 16px;
}
.tree-view li {
list-style-type: none;
margin: 0;
padding: 10px 5px 0;
position: relative;
}
.tree-view li:last-child {
margin-bottom: 10px;
}
.tree-view li::after,
.tree-view li::before {
content: '';
left: -30px;
position: absolute;
right: auto;
}
.tree-view li::before {
border-left: 1px solid #405567;
height: calc(100% + 10px);
top: 0;
width: 1px;
}
.tree-view li::after {
border-top: 1px solid #405567;
height: 20px;
top: 20px;
width: 35px;
}
.tree-view .item {
border: 1px solid #405567;
border-radius: 2px;
background-color: #fff;
display: inline-block;
padding: 2px 6px;
text-decoration: none;
cursor: pointer;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
}
.tree-view .folder {
background-color: #fbf897;
}
.tree-view>ul>li::after,
.tree-view>ul>li::before {
border: 0;
}
.tree-view li:last-child::before {
height: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<script type="text/x-template" id="item-template">
<li>
<div class="item" :class="{folder: isFolder}" @click="toggle">
<span v-if="isFolder">{{ open ? '-' : '+' }}</span> {{ model.name }}
</div>
<ul v-show="open" v-if="isFolder">
<item v-for="(model, index) in model.children" :key="index" :model="model">
</item>
</ul>
</li>
</script>
<div class="tree-view" id="main">
<ul>
<item :model="treeData">
</item>
</ul>
</div>
Upvotes: 2