通过一个树状组件,研究一下组件的递归;
递归组件注意:
1. 组件要加上 name
属性;
2. 在循环中,调用自身;
3. 适当的时候结束递归;
4. 适当的数据(可以递归循环);
好了,话不多说,开始制作树状组件;
1)看一下要用的数据结构
[
{
name: '山东省',
show: true,
children: [
{
name: '潍坊市',
show: true,
children: [
{
name: '临朐县',
show: true,
},
{
name: '潍城区',
show: true,
}
]
},
{
name: '日照市',
show: true,
children: [
{
name: '岚山区',
show: true,
},
{
name: '五莲县',
show: true,
}
]
},
{
name: '济南市',
show: true,
children: [
{
name: '市中区',
show: true,
},
{
name: '高新区',
show: true,
}
]
},
]
},
{
name: '陕西省',
show: true,
children: [
{
name: '西安市',
show: true,
children: [
{
name: '未央区',
show: true,
},
{
name: '莲湖区',
show: true,
children: [
{
name: '红庙坡街道',
show: true,
},
{
name: '梨园路',
show: true,
}
]
},
{
name: '浐灞',
show: true,
},
]
},
{
name: '咸阳市',
show: true,
},
{
name: '汉中市',
show: true,
}
]
}
]
2)开始编写组件
Vue.component('Tree', {
// 【注意 1】要做递归,要加上name属性;
// 全局组件可以不要,因为会自动生成,局部组件一定要添加上 name
name: 'Tree',
props: {
treeData: Array
},
template: `
<ul>
<!--【注意 2】在循环的 li里边,调用了自身组件-->
<li v-for="item in treeData">
<p @click="item.show = !item.show">{{item.name}}</p>
<Tree :treeData="item.children"
v-if="Array.isArray(item.children)"
v-show="item.show"/>
</li>
</ul>
`,
});
解释:
treeData
是上边的数据;传入到组件中;
组件通过 <li>
循环;首先读取出地区名称来;也就是 <p>
标签中的内容;
然后,需要在这个地区下面跟上下级地区的名称,数据那里来的呢,就是循环 <li>
这条数据的 children
项,就是下级数据,所以就在此处,再次调用自身;
然后通过检查 可能是下级的下级,还有没有 children
项,如果没有了,就不再执行 自身<Tree>
组件了;
然后点击收起是怎么实现的呢?
<p>
和 <li>
内的 <Tree>
使用的数据是同一条,所以点击 <p>
之后,转化了状态,下边的本条数据chilren
的就不可见了;
好吧,我也感觉自己没有讲解的很明白…
感觉意思明白,但是转化成文字不好描述,这个得多次练习,熟能生巧;
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app"></div>
<script>
Vue.component('Tree', {
// 【注意 1】要做递归,要加上name属性;
// 全局组件可以不要,因为会自动生成,局部组件一定要添加上 name
name: 'Tree',
props: {
treeData: Array
},
template: `
<ul>
<!--【注意 2】在循环的 li里边,调用了自身组件-->
<li v-for="item in treeData">
<p @click="item.show = !item.show">{{item.name}}</p>
<Tree :treeData="item.children"
v-if="Array.isArray(item.children)"
v-show="item.show"/>
</li>
</ul>
`,
});
new Vue({
el: "#app",
template: `
<Tree :treeData="treeData"/>
`,
data: {
treeData:
[
{
name: '山东省',
show: true,
children: [
{
name: '潍坊市',
show: true,
children: [
{
name: '临朐县',
show: true,
},
{
name: '潍城区',
show: true,
},
{
name: '奎文区',
show: true,
},
{
name: '寿光县',
show: true,
}
]
},
{
name: '日照市',
show: true,
children: [
{
name: '岚山区',
show: true,
},
{
name: '五莲县',
show: true,
}
]
},
{
name: '济南市',
show: true,
children: [
{
name: '市中区',
show: true,
},
{
name: '高新区',
show: true,
},
{
name: '章区',
show: true,
},
{
name: '槐荫区',
show: true,
}
]
},
]
},
{
name: '陕西省',
show: true,
children: [
{
name: '西安市',
show: true,
children: [
{
name: '未央区',
show: true,
},
{
name: '莲湖区',
show: true,
children: [
{
name: '红庙坡街道',
show: true,
},
{
name: '梨园路',
show: true,
}
]
},
{
name: '高新区',
show: true,
},
{
name: '浐灞',
show: true,
}
]
},
{
name: '咸阳市',
show: true,
},
{
name: '汉中市',
show: true,
}
]
}
]
},
})
</script>
</body>
</html>
学如逆水行舟,不进则退!
望吾辈共勉!