当有一组数据,有层层嵌套的关系(item.child),如何渲染在页面上呢
list: [{
label: "AAA",
children: [{
label: "AAA-1",
children: []},
{label: "AAA-2",
children: [{
label: "AAA-2-1",
children: []},
{label: "AAA-2-2",
children: []}, {
label: "AAA-2-3",
children: []}]}, {
label: "AAA-3",children: []}
]},
特别是不知道层数的情况下,不能用不知数量的ul li进行嵌套,此时用到递归
话不多说,直接贴图
<div id='app' v-cloak>
<sb-tree style="margin:10px;background: #ccc;" :list='list'></sb-tree>
<sb-tree :list='list1' :keys='k1'></sb-tree>
</div>
<script>
Vue.component('sb-tree', {
template: `
<ul>
<li v-for='item in mylist'>
<i v-if="item.children && item.children.length" class="fa fa-chevron-right" aria-hidden="true"></i>
<span @click="item.isShow = !item.isShow">{{item.label}}</span>
<sb-tree style="padding-left:30px" v-show='item.isShow' :list = 'item.children' :keys='keys'></sb-tree> </li></ul>
`,
props: {
list: {
type: Array,
require: true, },
keys: {
type: Object,
default () {
return {
label: 'label',
children: 'children'
} } } },
data() {
return {
mylist:this.list.map(r => ({
label: r[this.keys.label],
children: r[this.keys.children],
isShow: false
}))}},
代码阐述
1.子组件中嵌套子组件组件
2.一层 v-for循环mylist数组,递归循环的是mylist.children直到没有children则停止
3.如何控制传入的值如果不为label和children还能渲染
方法一:
将传入的list 在data里进行map重新生成mylist(此处注意一定要是data而不是computed,因为computed不会实时更新isShow数据),将mylist里的label进行数据绑定赋值
方法二:
父组件传入keys值,此值为要渲染的list的内容名和子集名(label/name,children/cc),并设置默认值(注意object默认值和data写法一致)当不传入时显示item.label和item.children
4.控制点击item就自动展开item.children
步骤:①单纯给sb-tree设置v-show 则会全部显示或全部关闭item.children
②给item设置isShow值,默认为false(list在data里map成mylist,并加入isShow属性)
③ 给item 加span标签,并设置@click事件
@click=”item.isShow = !item.isShow“
并给item.children设置v-show=’item.isShow‘
item.children的展示和隐藏会跟着父级的item.isShow走,因为绑定了点击事件,仅仅会触发点击的item->item.children