看一下效果
效果图index.vue
创建ul 并且使用v-for循环 data是调用组件传过来的值
<template>
<div>
<ul v-for="(item, index) in data" :key="index">
<tree-item :data="item"></tree-item>
</ul>
</div>
</template>
写一下子组件传给父组件的值的类型 data是必填的
props: {
data: {
type: [Object, Array],
required: true
}
}
treeItem.vue
创建li 并且使用v-for循环
<li>
<span @click="toggle(data)">
<span v-if="hasChild">{{ isOpen ? "-" : "+" }}</span>
{{ data[text] }}
</span>
</li>
toggle是切换显示隐藏的子级 hasChild判断是否还有子级,如果有子级则用+/-来显示打开或关闭状态
因为可能子级还会有子级,所以需要组件嵌套 所以在li里面嵌套一个ul
<ul v-show="isOpen" v-if="hasChild">
<tree-item
v-for="(item, index) in data[children]"
:data="item"
:key="index"
:treeProps="treeProps"
></tree-item>
</ul>
因为使用了组件嵌套,则需要给该组件定一个名称
export default {
name: "TreeItem",
props: {
data: {
type: [Object, String],
required: true
}
},
data: {
isOpen: false
}
}
因为hasChild需要实时更新,所以试用了计算属性computed
computed: {
// 判断当前级别是否还有children
hasChild() {
return (
this.data[children] && this.data[children].length;
);
}
}
点击子菜单判断是否有children,有就展开
toggle(data) {
if (this.hasChild) {
this.isOpen = !this.isOpen;
data.open = this.isOpen;
}
}
然后简单的写一下样式
<style>
ul {
list-style: none;
padding-left: 20px;
}
li {
color: #000;
}
li > span {
cursor: pointer;
font-size: 14px;
line-height: 20px;
}
</style>
最后附上全部代码
index.vue
<template>
<div>
<ul v-for="(item, index) in data" :key="index">
<tree-item :data="item"></tree-item>
</ul>
</div>
</template>
<script>
import treeItem from "./item";
export default {
props: {
data: {
type: [Object, Array],
required: true
}
},
components: {
treeItem
}
};
</script>
item.vue
<template>
<li>
<span @click="toggle(data)">
<span v-if="hasChild">{{ isOpen ? "-" : "+" }}</span>
{{
data[text]
}}
</span>
<ul v-show="isOpen" v-if="hasChild">
<tree-item
v-for="(item, index) in data[children]"
:data="item"
:key="index"
:treeProps="treeProps"
></tree-item>
</ul>
</li>
</template>
<script>
import { getTree, keyword } from "../../views/mapShow/PJKeyVideo/api/api";
export default {
name: "TreeItem", //递归组件必须有name
props: {
data: {
type: [Object, Array], //多个可能的类型
required: true
}
},
data() {
return {
isOpen: false
};
},
computed: {
// 判断当前级别是否还有children
hasChild() {
return (
this.data[children] && this.data[children].length;
);
}
},
methods: {
// 点击子菜单也要判断是否有children,有就展开
toggle(data) {
if (this.hasChild) {
this.isOpen = !this.isOpen;
}
},
}
};
</script>
<style>
ul {
list-style: none;
padding-left: 20px;
}
li {
color: #000;
}
li > span {
cursor: pointer;
font-size: 14px;
line-height: 20px;
}
</style>
数据格式
treeData: [
{
children: [
{
children: [
{
text: "沈阳市"
},
{
text: "大连市"
}
],
text: "辽宁省"
}
],
text: "主控制中心"
}
]
网友评论