赞
踩
树形组件:用清晰的层级结构展示信息,可展开或折叠。
树组件使用挺频繁的,常见于侧边栏树形目录、树形下拉选项按钮或搜索查询树形信息选项
基础的树形结构展示
- <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() > 0.5;
- }
-
- setTimeout(() => {
- var data;
- if (hasChild) {
- data = [{
- name: 'zone' + this.count++
- }, {
- name: 'zone' + this.count++
- }];
- } else {
- data = [];
- }
-
- resolve(data);
- }, 500);
- }
- }
- };
- </script>
- /*由于在点击节点时才进行该层数据的获取,默认情况下 Tree 无法预知某个节点是否为叶子节点,所以会为每个节点添加一个下拉按钮,如果节点没有下层数据,则点击后下拉按钮会消失。同时,你也可以提前告知 Tree 某个节点是否为叶子节点,从而避免在叶子节点前渲染下拉按钮。*/
-
- <el-tree
- :props="props"
- :load="loadNode"
- lazy
- show-checkbox>
- </el-tree>
-
- <script>
- export default {
- data() {
- return {
- props: {
- label: 'name',
- children: 'zones',
- isLeaf: 'leaf'
- },
- };
- },
- methods: {
- loadNode(node, resolve) {
- if (node.level === 0) {
- return resolve([{ name: 'region' }]);
- }
- if (node.level > 1) return resolve([]);
-
- setTimeout(() => {
- const data = [{
- name: 'leaf',
- leaf: true
- }, {
- name: 'zone'
- }];
-
- resolve(data);
- }, 500);
- }
- }
- };
- </script>
可将 Tree 的某些节点设置为默认展开或默认选中
- /*分别通过default-expanded-keys和default-checked-keys设置默认展开和默认选中的节点。需要注意的是,此时必须设置node-key,其值为节点数据中的一个字段名,该字段在整棵树中是唯一的。*/
-
- <el-tree
- :data="data"
- show-checkbox
- node-key="id"
- :default-expanded-keys="[2, 3]"
- :default-checked-keys="[5]"
- :props="defaultProps">
- </el-tree>
-
- <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>
可将 Tree 的某些节点设置为禁用状态
- //通过disabled设置禁用状态。
-
- <el-tree
- :data="data"
- show-checkbox
- node-key="id"
- :default-expanded-keys="[2, 3]"
- :default-checked-keys="[5]">
- </el-tree>
-
- <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>
- /*如何获取和设置选中节点。获取和设置各有两种方式:通过 node 或通过 key。如果需要通过 key 来获取或设置,则必须设置node-key。*/
-
- <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>
-
- <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>
节点的内容支持自定义,可以在节点区添加按钮或图标等内容
- /*可以通过两种方法进行树节点内容的自定义:render-content和 scoped slot。使用render-content指定渲染函数,该函数返回需要的节点区内容即可。渲染函数的用法请参考 Vue 文档。使用 scoped slot 会传入两个参数node和data,分别表示当前节点的 Node 对象和当前节点的数据。注意:由于 jsfiddle 不支持 JSX 语法,所以render-content示例在 jsfiddle 中无法运行。但是在实际的项目中,只要正确地配置了相关依赖,就可以正常运行。*/
-
- <div class="custom-tree-container">
- <div class="block">
- <p>使用 render-content</p>
- <el-tree
- :data="data"
- 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="data"
- 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 {
- data: JSON.parse(JSON.stringify(data)),
- data: 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 => 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>
通过关键字过滤树节点
- /*在需要对节点进行过滤时,调用 Tree 实例的filter方法,参数为关键字。需要注意的是,此时需要设置filter-node-method,值为过滤函数。*/
-
- <el-input
- placeholder="输入关键字进行过滤"
- v-model="filterText">
- </el-input>
-
- <el-tree
- class="filter-tree"
- :data="data"
- :props="defaultProps"
- default-expand-all
- :filter-node-method="filterNode"
- ref="tree">
- </el-tree>
-
- <script>
- export default {
- watch: {
- filterText(val) {
- this.$refs.tree.filter(val);
- }
- },
-
- methods: {
- filterNode(value, data) {
- if (!value) return true;
- return 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>
对于同一级的节点,每次只能展开一个
- <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="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>
-
- <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>
上述内容即为Tree树组件的详细使用方法,若想深入浅出可以前往Tree组件 。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。