free-tree-list.vue
<template>
<li>
<span @click="toggle(model.id)">
<i v-if="isFolder" class="icon" :class="[open ? 'folder-open': 'folder']"></i>
<i v-if="!isFolder" class="icon file-text"></i>
{{ model.menuName }}
</span>
<ul style="padding-left: 16px" :class="{slideDown:!open,slideUp:open}" v-show="open" v-if="isFolder">
<free-tree-list @selectCaputure="onselect" v-for="item in model.children" :model="item" :key="item.id"></free-tree-list>
</ul>
</li>
</template>
<script>
export default {
name: 'free-tree-list',
props: ['model'],
data() {
return {
open: false
}
},
computed: {
isFolder: function() {
return this.model.children && this.model.children.length
}
},
methods: {
toggle: function(id) {
this.$emit('selectCaputure',id)
if (this.isFolder) {
this.open = !this.open
}
},
onselect(id){
this.$emit('selectCaputure',id);
}
}
}
</script>
<style>
ul {
list-style: none;
}
i.icon {
display: inline-block;
width: 15px;
height: 15px;
background-repeat: no-repeat;
vertical-align: middle;
background-size: cover;
}
.icon.folder {
background-image: url(/src/assets/文件夹1.png);
}
.icon.folder-open {
background-image: url(/src/assets/文件夹2.png);
}
.icon.file-text {
background-image: url(/src/assets/文件.png);
}
.tree-menu li {
line-height: 1.5;
}
.tree-menu li span{
cursor: pointer;
display: inline-block;
line-height: 30px;
}
.slideDown{
/* overflow-y: hidden;
max-height: 500px; !* approximate max height *!
transition-property: all;
transition-duration: 2s;
transition-timing-function: cubic-bezier(0, 1, 0.5, 1);*/
max-height: 0px;
overflow-y: hidden;
-webkit-transition: max-height 0.8s ease-in-out;
-moz-transition: max-height 0.8s ease-in-out;
-o-transition: max-height 0.8s ease-in-out;
transition: max-height 0.8s ease-in-out;
}
.slideUp{
max-height: 300px ;
}
</style>
free-tree.vue
<template>
<div class="tree-menu">
<ul v-for="menuItem in allData" :key="menuItem.id">
<free-tree-list @selectCaputure="onselect" :model="menuItem"></free-tree-list>
</ul>
</div>
</template>
<script>
import freeTreeList from './free-tree-list.vue'
export default {
props:{
allData:{
type:Array,
default:[]
}
},
components: {
freeTreeList
},
data() {
return {
}
},
methods:{
onselect(id){
this.$emit('selectCaputure',id);
}
}
}
</script>
App.vue(调用)
<template>
<div id="app">
<free-tree @selectCaputure="onselect" :allData="myData" class="trees"></free-tree>
</div>
</template>
<script>
var myData = [
{
'id': '1',
'menuName': '一级-01',
'menuCode': '10',
'children': [
{
'menuName': '二级-01',
'menuCode': '11',
'id': '11'
},
{
'menuName': '二级-02',
'menuCode': '12',
'id': '12',
'children': [
{
'menuName': '三级-02',
'menuCode': '121',
'id': '121'
},
{
'menuName': '三级-03',
'menuCode': '122',
'id': '122'
}
]
},
{
'menuName': '二级-03',
'menuCode': '13',
'id': '13'
}
]
},
{
'id': '2',
'menuName': '一级-02',
'menuCode': ''
},
{
'id': '3',
'menuName': '一级-03',
'menuCode': '30',
'children': [
{
'menuName': '二级-01',
'menuCode': '31',
'id': '31'
},
{
'menuName': '二级-02',
'menuCode': '32',
'id': '32',
'children': []
}
]
},
{
'id': '4',
'menuName': '一级-04',
'menuCode': '',
'children': []
}
];
import freeTree from './free-tree'
export default {
name: 'app',
methods:{
onselect(id){
console.log(id);
}
},
data () {
return {
myData:myData
}
},
components:{
freeTree
}
}
</script>
<style lang="scss">
.trees{
margin: 20px;
}
</style>