1. 程式人生 > 其它 >ElementUI 的Tree Tree 選單樹形控制元件

ElementUI 的Tree Tree 選單樹形控制元件

Tree 樹形控制元件

Tree 樹形控制元件

Tree 樹形控制元件

用清晰的層級結構展示資訊,可展開或摺疊。

基礎用法

基礎的樹形結構展示。

<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"></el-tree>

<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>

可選擇

適用於需要選擇層級時使用。

本例還展示了動態載入節點資料的方法。

<el-tree
:props="props"
:load="loadNode"
lazy
show-checkbox
@check-change="handleCheckChange">
</el-tree>

<script>
export default {
data() {
return {
props: {
label: 'name',
children: 'zones'
},
count: 1
};
},
methods: {
handleCheckChange(data, checked, indeterminate) {
console.log(data, checked, indeterminate);
},
handleNodeClick(data) {
console.log(data);
},
loadNode(node, resolve) {
if (node.level === 0) {
return resolve([{ name: 'region1' }, { name: 'region2' }]);
}
if (node.level > 3) return resolve([]);

    var hasChild;
    if (node.data.name === 'region1') {
      hasChild = true;
    } else if (node.data.name === 'region2') {
      hasChild = false;
    } else {
      hasChild = Math.random() &gt; 0.5;
    }

    setTimeout(() =&gt; {
      var data;
      if (hasChild) {
        data = [{
          name: 'zone' + this.count++
        }, {
          name: 'zone' + this.count++
        }];
      } else {
        data = [];
      }

      resolve(data);
    }, 500);
  }
}

};
</script>

懶載入自定義葉子節點

由於在點選節點時才進行該層資料的獲取,預設情況下 Tree 無法預知某個節點是否為葉子節點,所以會為每個節點新增一個下拉按鈕,如果節點沒有下層資料,則點選後下拉按鈕會消失。同時,你也可以提前告知 Tree 某個節點是否為葉子節點,從而避免在葉子節點前渲染下拉按鈕。

<el-tree
:props="props1"
:load="loadNode1"
lazy
show-checkbox>
</el-tree>

<script>
export default {
data() {
return {
props1: {
label: 'name',
children: 'zones',
isLeaf: 'leaf'
},
};
},
methods: {
loadNode1(node, resolve) {
if (node.level === 0) {
return resolve([{ name: 'region' }]);
}
if (node.level > 1) return resolve([]);

    setTimeout(() =&gt; {
      const data = [{
        name: 'leaf',
        leaf: true
      }, {
        name: 'zone'
      }];

      resolve(data);
    }, 500);
  }
}

};
</script>

預設展開和預設選中

可將 Tree 的某些節點設定為預設展開或預設選中

分別通過default-expanded-keysdefault-checked-keys設定預設展開和預設選中的節點。需要注意的是,此時必須設定node-key,其值為節點資料中的一個欄位名,該欄位在整棵樹中是唯一的。

<el-tree
:data="data2"
show-checkbox
node-key="id"
:default-expanded-keys="[2, 3]"
:default-checked-keys="[5]"
:props="defaultProps">
</el-tree>

<script>
export default {
data() {
return {
data2: [{
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>

禁用狀態

可將 Tree 的某些節點設定為禁用狀態

通過disabled設定禁用狀態。

<el-tree
:data="data3"
show-checkbox
node-key="id"
:default-expanded-keys="[2, 3]"
:default-checked-keys="[5]">
</el-tree>

<script>
export default {
data() {
return {
data3: [{
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>

樹節點的選擇

通過 node 獲取通過 key 獲取通過 node 設定通過 key 設定清空

本例展示如何獲取和設定選中節點。獲取和設定各有兩種方式:通過 node 或通過 key。如果需要通過 key 來獲取或設定,則必須設定node-key

<el-tree
:data="data2"
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>

<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 {
    data2: [{
      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>

自定義節點內容

節點的內容支援自定義,可以在節點區新增按鈕或圖示等內容

可以通過兩種方法進行樹節點內容的自定義:render-content和 scoped slot。使用render-content指定渲染函式,該函式返回需要的節點區內容即可。渲染函式的用法請參考 Vue 文件。使用 scoped slot 會傳入兩個引數nodedata,分別表示當前節點的 Node 物件和當前節點的資料。注意:由於 jsfiddle 不支援 JSX 語法,所以render-content示例在 jsfiddle 中無法執行。但是在實際的專案中,只要正確地配置了相關依賴,就可以正常執行。

<div class="custom-tree-container">
<div class="block">
<p>使用 render-content</p>
<el-tree
:data="data4"
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="data5"
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>

<script>
let id = 1000;

export 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 {
data4: JSON.parse(JSON.stringify(data)),
data5: 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.parent;
    const children = parent.data.children || parent.data;
    const index = children.findIndex(d =&gt; d.id === data.id);
    children.splice(index, 1);
  },

  renderContent(h, { node, data, store }) {
    return (
      &lt;span class="custom-tree-node"&gt;
        &lt;span&gt;{node.label}&lt;/span&gt;
        &lt;span&gt;
          &lt;el-button size="mini" type="text" on-click={ () =&gt; this.append(data) }&gt;Append&lt;/el-button&gt;
          &lt;el-button size="mini" type="text" on-click={ () =&gt; this.remove(node, data) }&gt;Delete&lt;/el-button&gt;
        &lt;/span&gt;
      &lt;/span&gt;);
  }
}

};
</script>

<style>
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
</style>

節點過濾

通過關鍵字過濾樹節點

在需要對節點進行過濾時,呼叫 Tree 例項的filter方法,引數為關鍵字。需要注意的是,此時需要設定filter-node-method,值為過濾函式。

<el-input
placeholder="輸入關鍵字進行過濾"
v-model="filterText">
</el-input>

<el-tree
class="filter-tree"
:data="data2"
:props="defaultProps"
default-expand-all
:filter-node-method="filterNode"
ref="tree2">
</el-tree>

<script>
export default {
watch: {
filterText(val) {
this.$refs.tree2.filter(val);
}
},

methods: {
  filterNode(value, data) {
    if (!value) return true;
    return data.label.indexOf(value) !== -1;
  }
},

data() {
  return {
    filterText: '',
    data2: [{
      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>

手風琴模式

對於同一級的節點,每次只能展開一個

<el-tree
:data="data"
:props="defaultProps"
accordion
@node-click="handleNodeClick">
</el-tree>

<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>

可拖拽節點

通過 draggable 屬性可讓節點變為可拖拽。

<el-tree
:data="data6"
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>

<script>
export default {
data() {
return {
data6: [{
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>

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

filter-node-method

對樹節點進行篩選時執行的方法,返回 true 表示這個節點可以顯示,返回 false 則表示這個節點會被隱藏

Function(value, data, node)

accordion

是否每次只打開一個同級樹節點展開

boolean

false

indent

相鄰級節點間的水平縮排,單位為畫素

number

16

lazy

是否懶載入子節點,需與 load 方法結合使用

boolean

false

draggable

是否開啟拖拽節點功能

boolean

false

allow-drag

判斷節點能否被拖拽

Function(node)

allow-drop

拖拽時判定目標節點能否被放置。type 引數有三種情況:'prev'、'inner' 和 'next',分別表示放置在目標節點前、插入至目標節點和放置在目標節點後

Function(draggingNode, dropNode, type)

props

引數

說明

型別

可選值

預設值

label

指定節點標籤為節點物件的某個屬性值

string, function(data, node)

children

指定子樹為節點物件的某個屬性值

string

disabled

指定節點選擇框是否禁用為節點物件的某個屬性值

boolean, function(data, node)

isLeaf

指定節點是否為葉子節點,僅在指定了 lazy 屬性的情況下生效

boolean, function(data, node)

方法

Tree 內部使用了 Node 型別的物件來包裝使用者傳入的資料,用來儲存目前節點的狀態。 Tree 擁有如下方法:

方法名

說明

引數

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

獲取當前被選中節點的 node,若沒有節點被選中則返回 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

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

Scoped Slot

name

說明

自定義樹節點的內容,引數為 { node, data }

本文件系騰訊云云+社群成員共同維護,如有問題請聯絡 [email protected]

https://cloud.tencent.com/developer/section/1489888