通過一個樹狀組件,研究一下組件的遞歸;
遞歸組件注意:
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>
學如逆水行舟,不進則退!
望吾輩共勉!