本身作個小項目練手,須要用到組件遞歸,網上查了一些資料,每一個代碼片斷都認識,可是連起來,就一團漿糊。ide
既然人傻就多思考吧。不明白的點有如下:函數
1.組件怎麼本身調用本身,函數的遞歸是就是在function fn(){ fn() },組件的遞歸沒有看到這樣子的呀。this
答:組件中使用name屬性,給組件本身定義個名字,這樣在組件中就能夠本身調用本身了。就像在函數中直接調用函數名來來遞歸。spa
2.組件的遞歸中一層又一層數據是如何獲取到的?code
答:將嵌套的數據從新賦值給prop設置的屬性。component
<tree-menu v-for="(item,index) in model.children" v-bind:model="item" v-bind:key="index"></tree-menu>
3.組件遞歸是怎麼結束的?blog
判斷數據中是否存在屬性,以及該屬性的值不爲空。見下面代碼中的haschild方法。遞歸
hasChild(){ return this.model.children && this.model.children.length }
下面的代碼來自https://www.jianshu.com/p/84eb67487113ip
var demoData = [ { 'id': '1', 'menuName': '基礎管理', 'menuCode': '10', 'children': [ { 'menuName': '用戶管理', 'menuCode': '11' }, { 'menuName': '角色管理', 'menuCode': '12', 'children': [ { 'menuName': '管理員', 'menuCode': '121' }, { 'menuName': 'CEO', 'menuCode': '122' }, { 'menuName': 'CFO', 'menuCode': '123' }, { 'menuName': 'COO', 'menuCode': '124' }, { 'menuName': '普通人', 'menuCode': '124' } ] }, { 'menuName': '權限管理', 'menuCode': '13' } ] }, { 'id': '2', 'menuName': '商品管理', 'menuCode': '' }, { 'id': '3', 'menuName': '訂單管理', 'menuCode': '30', 'children': [ { 'menuName': '訂單列表', 'menuCode': '31' }, { 'menuName': '退貨列表', 'menuCode': '32', 'children': [] } ] }, { 'id': '4', 'menuName': '商家管理', 'menuCode': '', 'children': [] } ]; export default demoData;
<template> <div class="tree-menu"> <ul v-for="menuItem in theModel">
//使用子組件,並將數據傳給子組件的model屬性上,供子組件使用。 <my-tree :model="menuItem"></my-tree> </ul> </div> </template> <script> import testData from './testdata'; import myTree from './treeMenu'; export default {
//name屬性是組件的名字,這樣組件才能調用組件本身。 name: "side-bar", components: {
//即treeMenu文件,它在side-bar組件中的名字設置爲了myTree。 myTree }, data() { return {
//綁定數據供v-for循環使用。 theModel: testData } } } </script>
<template> <li>
//控制圖標的顯示 <span @click="toggle"> <i v-if="hasChild" class="icon" v-bind:class="[open ? 'folder-open': 'folder' ]"></i> <i v-if="!hasChild" class="icon file-text"></i> {{model.menuName}} </span>
//判斷數據中是否有可遍歷的屬性。 <ul v-show="open" v-if="hasChild">
//若是有可遍歷的屬性,調用組件本身(tree-menu),獲取下一層能夠遍歷的數據,將下一層可遍歷屬性綁定到model做爲model新的數據。
//key用來標識組件的惟一性,避免重複渲染。
<tree-menu v-for="(item,index) in model.children" v-bind:model="item" v-bind:key="index"></tree-menu> </ul> </li> </template> <script> export default {
//name屬性定義組件名,有了名字組件才能夠調用本身。 name: "treeMenu", props: ['model'], data(){ return { open:false } }, computed:{ hasChild(){
//有children屬性且屬性值的長度不爲零,那麼就遞歸。 return this.model.children && this.model.children.length } }, methods:{ toggle(){ if(this.hasChild){ this.open = !this.open } } } } </script>