vue中的遞迴元件實現樹結構
阿新 • • 發佈:2022-04-11
效果圖
元件說明
此元件為一個遞迴元件,實現頁面樹結構,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屬性,要不找不到註冊元件