效果圖
組件說明
此組件為一個遞歸組件,實現頁面樹結構,app上建議樹結構最多為3層,否則難以展示數據
基本使用
<m-tree :load="loadNode"></m-tree>
loadNode(node, resolve) {
//console.log(node);
if (node == null) {
setTimeout(() => {
//第一次調用
let res = [{
id: 1,
text: '公司1',
isExistChildNode: true, //是否存在子節點
extra: {
usercode: '00000001',
prjid: '1234567890'
} //額外的參數
}, {
id: 2,
text: '公司2',
isExistChildNode: false, //是否存在子節點
extra: {
usercode: '00000002',
prjid: '1234567890'
} //額外的參數
}]
return resolve(res);
}, 1000)
} else {
if (node.isExistChildNode) {
setTimeout(() => {
//開始遞歸
let res = [{
id: 11,
text: '部門1',
isExistChildNode: false, //是否存在子節點
extra: {
usercode: '00000011',
prjid: '1234567890'
} //額外的參數
}, {
id: 12,
text: '部門2',
isExistChildNode: false, //是否存在子節點
extra: {
usercode: '00000012',
prjid: '1234567890'
} //額外的參數
}]
return resolve(res);
}, 1000);
} else {
return resolve(null);
}
}
}
Props
參數 | 說明 | 類型 | 默認值 | 可選值 |
---|---|---|---|---|
load | 回調函數 | Function | 必填 | - |
nodeItem | 節點數據 | Object | null | - |
leavl | 樹的層級 | Number | 1,從1開始算層級 | - |
Events
事件名稱 | 說明 | 回調參數 |
---|---|---|
select | 選擇數據項 | e{};nodeItem節點數據 |
組件實現
<!-- -->
<template>
<view class="m-tree">
<view class="node" v-for="(item,index) in treeList" :key="index">
<view class="item">
<view class="left" @click="tapShowNode(item)">
<text v-if="item.isExistChildNode&&item.showChildren" class="icondemo demo-jianqu left-icon"></text>
<text v-else-if="item.isExistChildNode" class="icondemo demo-jia left-icon"></text>
</view>
<view class="right" @click="tapSelect(item)">
<text>{{item.text}}</text>
</view>
</view>
<m-tree v-if="item.showChildren" :nodeItem="item" :leavl="(leavl+1)" :load="load"></m-tree>
</view>
</view>
</template>
<script>
import {bus} from '@/libs/bus.js';
export default {
name:"m-tree", //遞歸組件必須有name屬性,要不找不到注冊組件
props: {
load: {
type: Function,
required: true
},
nodeItem: {
type: Object,
// 對象或數組默認值必須從一個工廠函數獲取
default: function() {
return null
}
},
leavl: {
type: Number,
default: 1 //層級
}
},
data() {
return {
treeList: []
}
},
created() {
let that = this;
this.load(this.nodeItem, (data) => {
if (data != null) {
data.forEach((item) => {
item.showChildren = false;
item.leavl = that.leavl;
});
this.treeList = data;
//console.log(data);
} else {
this.treeList = [];
}
});
},
//頁面渲染完成
mounted() {
},
watch: {
},
/**
* 計算屬性
*/
computed: {
},
methods: {
tapSelect(item){
//console.log(item);
bus.$emit('select',item);
},
tapShowNode(item){
item.showChildren = !item.showChildren;
}
}
}
</script>
<style lang="scss" scoped>
.m-tree {
padding-left: 20rpx;
.node {
.item {
padding: 30rpx 20rpx 30rpx 0;
display: flex;
align-items: center;
border-bottom: 1px solid #F2F6FC;
.left {
width: 100rpx;
display: flex;
justify-content: center;
.left-icon {
color: #409EFF;
font-size: 48rpx;
}
}
.right {
width: 400rpx;
font-size: 32rpx;
}
}
}
}
</style>
補充說明
-
遞歸組件不能使用this.$emit('select',item);來給父組件傳值了,因為子組件中即存在子組件又存在父組件,可以通過EventBus來監聽
-
使用方法
//引用
import {
bus
} from '@/libs/bus.js';
//父組件中監聽
onLoad() {
bus.$on('select', e => {
console.log(e);
})
},
//引用
import {
bus
} from '@/libs/bus.js';
//子組件傳值
tapSelect(item){
//console.log(item);
bus.$emit('select',item);
},
//bus.js文件
import Vue from "vue"
export const bus=new Vue();
- 遞歸組件必須有name屬性,要不找不到注冊組件