<div class="vue-app">
<root v-bind:folder="root"></root>
</div>
<script type="text/x-template" id="folders-component">
<template>
<ul class="folders">
<li>Folders</li>
<folder v-bind:folder="folder"></folder>
</ul>
</template>
</script>
<script type="text/x-template" id="folder-component">
<template>
<li class="folder" v-bind:class="[folder.leaf ? 'is-leaf' : 'is-folder']">
<span v-on:click="expand()">{{ folder.text }}</span>
<ul class="sub-folders" v-if="folder.children && folder.children.length > 0" v-show="folder.expanded">
<folder v-for="child in folder.children" v-bind:folder="child"></folder>
</ul>
<div class="folder-empty" v-else v-show="!folder.leaf && folder.expanded">No Data</div>
</li>
</template>
</script>
.vue-app {
margin: 0 auto;
width: 300px
}
ul.folders {
padding: 1rem;
margin: 0;
box-sizing: border-box;
width: 100%;
list-style: none
}
ul.folders > li:first-child {
padding: 1rem 1rem 1rem 0
}
li.is-folder {
padding: 1rem;
border-left: 1px solid #d3d3d3;
margin-bottom: 0.5rem
}
li.is-folder > span {
padding: 0.5rem;
border: 1px solid #d3d3d3;
cursor: pointer;
display:inline-block
}
li.is-leaf {
padding: 0 0 0 1rem;
color: #000;
}
ul.sub-folders {
padding: 1rem 1rem 0 0;
margin: 0;
box-sizing: border-box;
width: 100%;
list-style: none
}
div.folder-empty {
padding: 1rem 1rem 0 1rem;
color: #000;
opacity: 0.5
}
const root = {
text: 'Root Folder',
leaf: false,
expanded: true,
children: [{
text: 'Sub Folder 1',
leaf: false,
expanded: false,
children: [{
text: 'Sub Sub Folder 1',
leaf: false,
expanded: false,
children: [{
text: 'SomeFile1.js',
leaf: true
}]
}, {
text: 'Sub Sub Folder 2',
leaf: false,
expanded: false,
children: []
}, {
text: 'SomeFile.txt',
leaf: true
}]
}]
};
const folder = {
name: "folder",
template: '#folder-component',
props: {
folder: Object
},
methods: {
expand() {
if (this.folder.leaf) {
return;
}
this.folder.expanded = !this.folder.expanded;
}
}
}
const folders = {
name: 'root',
template: '#folders-component',
props: {
folder: Object
},
components: {
'folder': folder
}
}
new Vue({
el: '.vue-app',
data: () => {
return root;
},
components: {
'root': folders
}
});
This Pen doesn't use any external CSS resources.