025_Tree树形控件
1. Tree樹形控件
1.1. Tree樹形控件用清晰的層級結構展示信息, 可展開或折疊。
1.2. Tree樹形控件內部使用了Node類型的對象來包裝用戶傳入的數據, 用來保存目前節點的狀態。
1.3. Attributes
| 參數 | 說明 | 類型 | 可選值 | 默認值 |
| data | 展示數據 | array | 無 | 無 |
| empty-text | 內容為空的時候展示的文本 | String | 無 | 無 |
| node-key | 每個樹節點用來作為唯一標識的屬性, 整棵樹應該是唯一的 | String | 無 | 無 |
| props | 配置選項, 具體看下表 | object | 無 | |
| render-after-expand | 是否在第一次展開某個樹節點后才渲染其子節點 | boolean | 無 | true |
| load | 加載子樹數據的方法, 僅當lazy屬性為true時生效 | function(node, resolve) | 無 | 無 |
| render-content | 樹節點的內容區的渲染Function | Function(h, { node, data, store } | 無 | 無 |
| highlight-current | 是否高亮當前選中節點, 默認值是false。 | boolean | 無 | false |
| default-expand-all | 是否默認展開所有節點 | boolean | 無 | false |
| expand-on-click-node | 是否在點擊節點的時候展開或者收縮節點, 默認值為true, 如果為false, 則只有點箭頭圖標的時候才會展開或者收縮節點。 | boolean | 無 | true |
| check-on-click-node | 是否在點擊節點的時候選中節點, 默認值為false, 即只有在點擊復選框時才會選中節點。 | boolean | 無 | false |
| auto-expand-parent | 展開子節點的時候是否自動展開父節點 | boolean | 無 | true |
| default-expanded-keys | 默認展開的節點的key的數組 | array | 無 | 無 |
| show-checkbox | 節點是否可被選擇 | boolean | 無 | false |
| check-strictly | 在顯示復選框的情況下, 是否嚴格的遵循父子不互相關聯的做法, 默認為false | boolean | 無 | false |
| default-checked-keys | 默認勾選的節點的key的數組 | array | 無 | 無 |
| current-node-key | 當前選中的節點 | string, number | 無 | 無 |
| filter-node-method | 對樹節點進行篩選時執行的方法, 返回true表示這個節點可以顯示, 返回false則表示這個節點會被隱藏 | Function(value, data, node) | 無 | 無 |
| accordion | 是否每次只打開一個同級樹節點展開 | boolean | 無 | false |
| indent | 相鄰級節點間的水平縮進, 單位為像素 | number | 無 | 16 |
| icon-class | 自定義樹節點的圖標 | string | 無 | 無 |
| lazy | 是否懶加載子節點, 需與load方法結合使用 | boolean | 無 | false |
| draggable | 是否開啟拖拽節點功能 | boolean | 無 | false |
| allow-drag | 判斷節點能否被拖拽 | Function(node) | 無 | 無 |
| allow-drop | 拖拽時判定目標節點能否被放置。type參數有三種情況: 'prev'、'inner'和'next', 分別表示放置在目標節點前、插入至目標節點和放置在目標節點后 | Function(draggingNode, dropNode, type) | 無 | 無 |
1.4. props
| 參數 | 說明 | 類型 |
| label | 指定節點標簽為節點對象的某個屬性值 | string, function(data, node) |
| children | 指定子樹為節點對象的某個屬性值 | string |
| disabled | 指定節點選擇框是否禁用為節點對象的某個屬性值 | boolean, function(data, node) |
| isLeaf | 指定節點是否為葉子節點, 僅在指定了lazy屬性的情況下生效 | boolean, function(data, node) |
1.5. 方法
| 方法名 | 說明 | 參數 |
| filter | 對樹節點進行篩選操作 | 接收一個任意類型的參數, 該參數會在filter-node-method中作為第一個參數 |
| updateKeyChildren | 通過keys設置節點子元素, 使用此方法必須設置node-key屬性 | (key, data)接收兩個參數, 1.節點key 2.節點數據的數組 |
| getCheckedNodes | 若節點可被選擇(即show-checkbox為true), 則返回目前被選中的節點所組成的數組 | (leafOnly, includeHalfChecked)接收兩個boolean類型的參數, 1.是否只是葉子節點, 默認值為false 2.是否包含半選節點, 默認值為false |
| setCheckedNodes | 設置目前勾選的節點, 使用此方法必須設置node-key屬性 | (nodes)接收勾選節點數據的數組 |
| getCheckedKeys | 若節點可被選擇(即show-checkbox為true), 則返回目前被選中的節點的key所組成的數組 | (leafOnly)接收一個boolean類型的參數, 若為true則僅返回被選中的葉子節點的keys, 默認值為false |
| setCheckedKeys | 通過keys設置目前勾選的節點,使用此方法必須設置node-key屬性 | (keys, leafOnly)接收兩個參數, 1.勾選節點的key的數組 2.boolean類型的參數, 若為true則僅設置葉子節點的選中狀態, 默認值為false |
| setChecked | 通過key / data設置某個節點的勾選狀態, 使用此方法必須設置node-key屬性 | (key/data, checked, deep)接收三個參數, 1.勾選節點的key或者data 2.boolean 類型, 節點是否選中 3.boolean類型, 是否設置子節點, 默認為false |
| getHalfCheckedNodes | 若節點可被選擇(即show-checkbox為true), 則返回目前半選中的節點所組成的數組 | 無 |
| getHalfCheckedKeys | 若節點可被選擇(即show-checkbox為true), 則返回目前半選中的節點的key所組成的數組 | 無 |
| getCurrentKey | 獲取當前被選中節點的key, 使用此方法必須設置node-key屬性, 若沒有節點被選中則返回null | 無 |
| getCurrentNode | 獲取當前被選中節點的data, 若沒有節點被選中則返回null | 無 |
| setCurrentKey | 通過key設置某個節點的當前選中狀態, 使用此方法必須設置node-key屬性 | (key)待被選節點的key, 若為null則取消當前高亮的節點 |
| setCurrentNode | 通過node設置某個節點的當前選中狀態, 使用此方法必須設置node-key屬性 | (node)待被選節點的node |
| getNode | 根據data或者key拿到Tree組件中的node | (data)要獲得node的key或者data |
| remove | 刪除Tree中的一個節點, 使用此方法必須設置node-key屬性 | (data)要刪除的節點的data或者node |
| append | 為Tree中的一個節點追加一個子節點 | (data, parentNode)接收兩個參數, 1.要追加的子節點的data 2.子節點的parent的data、key或者node |
| insertBefore | 為Tree的一個節點的前面增加一個節點 | (data, refNode)接收兩個參數, 1.要增加的節點的data 2.要增加的節點的后一個節點的data、key或者node |
| insertAfter | 為Tree的一個節點的后面增加一個節點 | (data, refNode)接收兩個參數, 1.要增加的節點的data 2.要增加的節點的前一個節點的data、key或者node |
1.6. Events
| 事件名 | 說明 | 回調參數 |
| node-click | 節點被點擊時的回調 | 共三個參數, 依次為: 傳遞給data屬性的數組中該節點所對應的對象、節點對應的Node、節點組件本身。 |
| node-contextmenu | 當某一節點被鼠標右鍵點擊時會觸發該事件 | 共四個參數, 依次為: event、傳遞給data屬性的數組中該節點所對應的對象、節點對應的Node、節點組件本身。 |
| check-change | 節點選中狀態發生變化時的回調 | 共三個參數, 依次為: 傳遞給data屬性的數組中該節點所對應的對象、節點本身是否被選中、節點的子樹中是否有被選中的節點 |
| check | 當復選框被點擊的時候觸發 | 共兩個參數, 依次為: 傳遞給data屬性的數組中該節點所對應的對象、樹目前的選中狀態對象, 包含checkedNodes、checkedKeys、halfCheckedNodes、halfCheckedKeys四個屬性 |
| current-change | 當前選中節點變化時觸發的事件 | 共兩個參數, 依次為: 當前節點的數據, 當前節點的Node對象 |
| node-expand | 節點被展開時觸發的事件 | 共三個參數, 依次為: 傳遞給data屬性的數組中該節點所對應的對象、節點對應的Node、節點組件本身 |
| node-collapse | 節點被關閉時觸發的事件 | 共三個參數, 依次為: 傳遞給data屬性的數組中該節點所對應的對象、節點對應的Node、節點組件本身 |
| node-drag-start | 節點開始拖拽時觸發的事件 | 共兩個參數, 依次為: 被拖拽節點對應的Node、event |
| node-drag-enter | 拖拽進入其他節點時觸發的事件 | 共三個參數, 依次為: 被拖拽節點對應的Node、所進入節點對應的Node、event |
| node-drag-leave | 拖拽離開某個節點時觸發的事件 | 共三個參數, 依次為: 被拖拽節點對應的Node、所離開節點對應的Node、event |
| node-drag-over | 在拖拽節點時觸發的事件(類似瀏覽器的mouseover事件) | 共三個參數, 依次為: 被拖拽節點對應的Node、當前進入節點對應的Node、event |
| node-drag-end | 拖拽結束時(可能未成功)觸發的事件 | 共四個參數, 依次為: 被拖拽節點對應的Node、結束拖拽時最后進入的節點(可能為空)、被拖拽節點的放置位置(before、after、inner)、event |
| node-drop | 拖拽結束時(可能未成功)觸發的事件 | 共四個參數, 依次為: 被拖拽節點對應的Node、結束拖拽時最后進入的節點、被拖拽節點的放置位置(before、after、inner)、event |
1.7. Scoped Slot
| name | 說明 |
| — | 自定義樹節點的內容, 參數為 { node, data } |
2. Tree樹形控件例子
2.1. 使用腳手架新建一個名為element-ui-tree的前端項目, 同時安裝Element插件。
2.2. 編輯index.js?
import Vue from 'vue' import VueRouter from 'vue-router' import BaseTree from '../components/BaseTree.vue' import ShowCheckboxTree from '../components/ShowCheckboxTree.vue' import DefaultExpandedCheckedKeysTree from '../components/DefaultExpandedCheckedKeysTree.vue' import DisabledTree from '../components/DisabledTree.vue' import NodeKeyTree from '../components/NodeKeyTree.vue' import RenderContentScopedSlotTree from '../components/RenderContentScopedSlotTree.vue' import FilterTree from '../components/FilterTree.vue' import AccordionTree from '../components/AccordionTree.vue' import DraggableTree from '../components/DraggableTree.vue'Vue.use(VueRouter)const routes = [{ path: '/', redirect: '/BaseTree' },{ path: '/BaseTree', component: BaseTree },{ path: '/ShowCheckboxTree', component: ShowCheckboxTree },{ path: '/DefaultExpandedCheckedKeysTree', component: DefaultExpandedCheckedKeysTree },{ path: '/DisabledTree', component: DisabledTree },{ path: '/NodeKeyTree', component: NodeKeyTree },{ path: '/RenderContentScopedSlotTree', component: RenderContentScopedSlotTree },{ path: '/FilterTree', component: FilterTree },{ path: '/AccordionTree', component: AccordionTree },{ path: '/DraggableTree', component: DraggableTree } ]const router = new VueRouter({routes })export default router2.3. 在components下創建BaseTree.vue
<template><div><h1>基礎用法</h1><h4>基礎的樹形結構展示。</h4><el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"></el-tree></div> </template><script> export default {data () {return {data: [{label: '一級 1',children: [{label: '二級 1-1',children: [{label: '三級 1-1-1'}]}]}, {label: '一級 2',children: [{label: '二級 2-1',children: [{label: '三級 2-1-1'}]}, {label: '二級 2-2',children: [{label: '三級 2-2-1'}]}]}, {label: '一級 3',children: [{label: '二級 3-1',children: [{label: '三級 3-1-1'}]}, {label: '二級 3-2',children: [{label: '三級 3-2-1'}]}]}],defaultProps: {children: 'children',label: 'label'}}},methods: {handleNodeClick (data) {console.log(data)}} } </script>2.4. 在components下創建ShowCheckboxTree.vue
<template><div><h1>可選擇</h1><h4>適用于需要選擇層級時使用。</h4><h4>由于在點擊節點時才進行該層數據的獲取, 默認情況下Tree無法預知某個節點是否為葉子節點, 所以會為每個節點添加一個下拉按鈕, 如果節點沒有下層數據, 則點擊后下拉按鈕會消失。同時, 你也可以提前告知Tree某個節點是否為葉子節點, 從而避免在葉子節點前渲染下拉按鈕。</h4><el-tree :props="props" :load="loadNode" lazy show-checkbox @check-change="handleCheckChange"></el-tree></div> </template><script> export default {data () {return {props: {label: 'name',children: 'zones'},count: 1}},methods: {handleCheckChange (data, checked, indeterminate) {console.log(data, checked, indeterminate)},loadNode (node, resolve) {if (node.level === 0) {return resolve([{ name: 'region1' }, { name: 'region2' }])}if (node.level > 3) return resolve([])var hasChildif (node.data.name === 'region1') {hasChild = true} else if (node.data.name === 'region2') {hasChild = false} else {hasChild = Math.random() > 0.5}setTimeout(() => {var dataif (hasChild) {data = [{name: 'zone' + this.count++}, {name: 'zone' + this.count++}]} else {data = []}resolve(data)}, 500)}} } </script>2.5. 在components下創建DefaultExpandedCheckedKeysTree.vue
<template><div><h1>默認展開和默認選中-可將Tree的某些節點設置為默認展開或默認選中</h1><h4>分別通過default-expanded-keys和default-checked-keys設置默認展開和默認選中的節點。需要注意的是, 此時必須設置node-key, 其值為節點數據中的一個字段名, 該字段在整棵樹中是唯一的。</h4><el-tree :data="data" show-checkbox node-key="id" :default-expanded-keys="[2, 3]" :default-checked-keys="[5]" :props="defaultProps"></el-tree></div> </template><script> export default {data () {return {data: [{id: 1,label: '一級 1',children: [{id: 4,label: '二級 1-1',children: [{id: 9,label: '三級 1-1-1'}, {id: 10,label: '三級 1-1-2'}]}]}, {id: 2,label: '一級 2',children: [{id: 5,label: '二級 2-1'}, {id: 6,label: '二級 2-2'}]}, {id: 3,label: '一級 3',children: [{id: 7,label: '二級 3-1'}, {id: 8,label: '二級 3-2'}]}],defaultProps: {children: 'children',label: 'label'}}} } </script>2.6. 在components下創建DisabledTree.vue
<template><div><h1>禁用狀態</h1><h4>通過disabled, 可將Tree的某些節點設置為禁用狀態。</h4><el-tree :data="data" show-checkbox node-key="id" :default-expanded-keys="[2, 3]" :default-checked-keys="[5]"></el-tree></div> </template><script> export default {data () {return {data: [{id: 1,label: '一級 2',children: [{id: 3,label: '二級 2-1',children: [{id: 4,label: '三級 3-1-1'}, {id: 5,label: '三級 3-1-2',disabled: true}]}, {id: 2,label: '二級 2-2',disabled: true,children: [{id: 6,label: '三級 3-2-1'}, {id: 7,label: '三級 3-2-2',disabled: true}]}]}],defaultProps: {children: 'children',label: 'label'}}} } </script>2.7. 在components下創建NodeKeyTree.vue
<template><div><h1>樹節點的選擇</h1><h4>本例展示如何獲取和設置選中節點。獲取和設置各有兩種方式: 通過node或通過key。如果需要通過key來獲取或設置, 則必須設置node-key。</h4><el-tree :data="data" show-checkbox default-expand-all node-key="id" ref="tree" highlight-current :props="defaultProps"></el-tree><div class="buttons"><el-button @click="getCheckedNodes">通過 node 獲取</el-button><el-button @click="getCheckedKeys">通過 key 獲取</el-button><el-button @click="setCheckedNodes">通過 node 設置</el-button><el-button @click="setCheckedKeys">通過 key 設置</el-button><el-button @click="resetChecked">清空</el-button></div></div> </template><script> export default {methods: {getCheckedNodes () {console.log(this.$refs.tree.getCheckedNodes())},getCheckedKeys () {console.log(this.$refs.tree.getCheckedKeys())},setCheckedNodes () {this.$refs.tree.setCheckedNodes([{id: 5,label: '二級 2-1'}, {id: 9,label: '三級 1-1-1'}])},setCheckedKeys () {this.$refs.tree.setCheckedKeys([3])},resetChecked () {this.$refs.tree.setCheckedKeys([])}},data () {return {data: [{id: 1,label: '一級 1',children: [{id: 4,label: '二級 1-1',children: [{id: 9,label: '三級 1-1-1'}, {id: 10,label: '三級 1-1-2'}]}]}, {id: 2,label: '一級 2',children: [{id: 5,label: '二級 2-1'}, {id: 6,label: '二級 2-2'}]}, {id: 3,label: '一級 3',children: [{id: 7,label: '二級 3-1'}, {id: 8,label: '二級 3-2'}]}],defaultProps: {children: 'children',label: 'label'}}} } </script>2.8. 在components下創建RenderContentScopedSlotTree.vue
<template><div><h1>自定義節點內容</h1><h4>可以通過兩種方法進行樹節點內容的自定義: render-content和scoped slot。使用render-content指定渲染函數, 該函數返回需要的節點區內容即可。使用scoped slot會傳入兩個參數node和data, 分別表示當前節點的Node對象和當前節點的數據。</h4><div class="custom-tree-container"><div class="block"><p>使用render-content</p><el-tree :data="data1" show-checkbox node-key="id" default-expand-all :expand-on-click-node="false" :render-content="renderContent"></el-tree></div><div class="block"><p>使用scoped slot</p><el-tree :data="data2" show-checkbox node-key="id" default-expand-all :expand-on-click-node="false"><span class="custom-tree-node" slot-scope="{ node, data }"><span>{{ node.label }}</span><span><el-button type="text" size="mini" @click="() => append(data)">Append</el-button><el-button type="text" size="mini" @click="() => remove(node, data)">Delete</el-button></span></span></el-tree></div></div></div> </template><script> let id = 1000export default {data () {const data = [{id: 1,label: '一級 1',children: [{id: 4,label: '二級 1-1',children: [{id: 9,label: '三級 1-1-1'}, {id: 10,label: '三級 1-1-2'}]}]}, {id: 2,label: '一級 2',children: [{id: 5,label: '二級 2-1'}, {id: 6,label: '二級 2-2'}]}, {id: 3,label: '一級 3',children: [{id: 7,label: '二級 3-1'}, {id: 8,label: '二級 3-2'}]}]return {data1: JSON.parse(JSON.stringify(data)),data2: JSON.parse(JSON.stringify(data))}},methods: {append (data) {const newChild = { id: id++, label: 'testtest', children: [] }if (!data.children) {this.$set(data, 'children', [])}data.children.push(newChild)},remove (node, data) {const parent = node.parentconst children = parent.data.children || parent.dataconst index = children.findIndex(d => d.id === data.id)children.splice(index, 1)},renderContent (h, { node, data, store }) {return (<span class="custom-tree-node"><span>{node.label}</span><span><el-button size="mini" type="text" on-click={ () => this.append(data) }>Append</el-button><el-button size="mini" type="text" on-click={ () => this.remove(node, data) }>Delete</el-button></span></span>)}} } </script><style>.custom-tree-node {flex: 1;display: flex;align-items: center;justify-content: space-between;font-size: 14px;padding-right: 8px;} </style>2.9. 在components下創建FilterTree.vue
<template><div><h1>節點過濾-通過關鍵字過濾樹節點</h1><h4>在需要對節點進行過濾時, 調用 Tree 實例的filter方法, 參數為關鍵字。需要注意的是, 此時需要設置filter-node-method, 值為過濾函數。</h4><el-input placeholder="輸入關鍵字進行過濾" v-model="filterText"></el-input><el-tree :data="data" :props="defaultProps" default-expand-all :filter-node-method="filterNode" ref="tree"></el-tree></div> </template><script> export default {watch: {filterText (val) {this.$refs.tree.filter(val)}},methods: {filterNode (value, data) {if (!value) return truereturn data.label.indexOf(value) !== -1}},data () {return {filterText: '',data: [{id: 1,label: '一級 1',children: [{id: 4,label: '二級 1-1',children: [{id: 9,label: '三級 1-1-1'}, {id: 10,label: '三級 1-1-2'}]}]}, {id: 2,label: '一級 2',children: [{id: 5,label: '二級 2-1'}, {id: 6,label: '二級 2-2'}]}, {id: 3,label: '一級 3',children: [{id: 7,label: '二級 3-1'}, {id: 8,label: '二級 3-2'}]}],defaultProps: {children: 'children',label: 'label'}}} } </script>2.10. 在components下創建AccordionTree.vue
<template><div><h1>手風琴模式</h1><h4>accordion是否每次只打開一個同級樹節點展開。</h4><el-tree :data="data" :props="defaultProps" accordion></el-tree></div> </template><script> export default {data () {return {data: [{label: '一級 1',children: [{label: '二級 1-1',children: [{label: '三級 1-1-1'}]}]}, {label: '一級 2',children: [{label: '二級 2-1',children: [{label: '三級 2-1-1'}]}, {label: '二級 2-2',children: [{label: '三級 2-2-1'}]}]}, {label: '一級 3',children: [{label: '二級 3-1',children: [{label: '三級 3-1-1'}]}, {label: '二級 3-2',children: [{label: '三級 3-2-1'}]}]}],defaultProps: {children: 'children',label: 'label'}}} } </script>2.11. 在components下創建DraggableTree.vue
<template><div><h1>可拖拽節點</h1><h4>通過draggable屬性可讓節點變為可拖拽。</h4><el-tree :data="data" node-key="id" default-expand-all @node-drag-start="handleDragStart" @node-drag-enter="handleDragEnter" @node-drag-leave="handleDragLeave"@node-drag-over="handleDragOver" @node-drag-end="handleDragEnd" @node-drop="handleDrop" draggable :allow-drop="allowDrop" :allow-drag="allowDrag"></el-tree></div> </template><script> export default {data () {return {data: [{id: 1,label: '一級 1',children: [{id: 4,label: '二級 1-1',children: [{id: 9,label: '三級 1-1-1'}, {id: 10,label: '三級 1-1-2'}]}]}, {id: 2,label: '一級 2',children: [{id: 5,label: '二級 2-1'}, {id: 6,label: '二級 2-2'}]}, {id: 3,label: '一級 3',children: [{id: 7,label: '二級 3-1'}, {id: 8,label: '二級 3-2',children: [{id: 11,label: '三級 3-2-1'}, {id: 12,label: '三級 3-2-2'}, {id: 13,label: '三級 3-2-3'}]}]}],defaultProps: {children: 'children',label: 'label'}}},methods: {handleDragStart (node, ev) {console.log('drag start', node)},handleDragEnter (draggingNode, dropNode, ev) {console.log('tree drag enter: ', dropNode.label)},handleDragLeave (draggingNode, dropNode, ev) {console.log('tree drag leave: ', dropNode.label)},handleDragOver (draggingNode, dropNode, ev) {console.log('tree drag over: ', dropNode.label)},handleDragEnd (draggingNode, dropNode, dropType, ev) {console.log('tree drag end: ', dropNode && dropNode.label, dropType)},handleDrop (draggingNode, dropNode, dropType, ev) {console.log('tree drop: ', dropNode.label, dropType)},allowDrop (draggingNode, dropNode, type) {if (dropNode.data.label === '二級 3-1') {return type !== 'inner'} else {return true}},allowDrag (draggingNode) {return draggingNode.data.label.indexOf('三級 3-2-2') === -1}} } </script>2.12. 運行項目, 訪問http://localhost:8080/#/BaseTree
2.13. 運行項目, 訪問http://localhost:8080/#/ShowCheckboxTree
?
2.14. 運行項目, 訪問http://localhost:8080/#/DefaultExpandedCheckedKeysTree
2.15. 運行項目, 訪問http://localhost:8080/#/DisabledTree?
?
2.16. 運行項目, 訪問http://localhost:8080/#/NodeKeyTree
2.17. 運行項目, 訪問http://localhost:8080/#/RenderContentScopedSlotTree?
?2.18. 運行項目, 訪問http://localhost:8080/#/FilterTree
2.19. 運行項目, 訪問http://localhost:8080/#/AccordionTree
?
2.20. 運行項目, 訪問http://localhost:8080/#/DraggableTree
?
總結
以上是生活随笔為你收集整理的025_Tree树形控件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 028_Alert警告
- 下一篇: 029_Loading加载