『el-tree の 使用教程』

✅基本使用

基本使用

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

<script>
export default {
  data() {
    return {
      data: [
        {
          label: '一级 1',
          children: [
            {
              label: '二级 1-1',
              children: [{ label: '三级 1-1-1' }]
            }
          ]
        }
      ],
      // 💡当前为defaultProps的默认值,可不写
      defaultProps: {
        label: 'label',
        children: 'children'
      }
    }
  },
  methods: {
    // 获取当前数据对象
    // 比如 点击最后一项 输出 “{ label: '三级 1-1-1' }”
    handleNodeClick(node) {
      console.log(node)
    }
  }
}
</script>

✅复选+动态加载

在这里插入图片描述

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

<script>
export default {
  data() {
    return {
      defaultProps: {
        label: 'name',
        children: 'zones'
      }
    }
  },
  methods: {
    // 加载子树数据
    loadNode(node, resolve) {
      // 往第1级添加数据
      if (node.level === 0) { return resolve([{ name: '福建省' }, { name: '广东省' }]) }
      // 第4级不再加载
      if (node.level > 3) return resolve([])
      // 接下来,实现动态加载节点数据
      var hasChild
      if (node.data.name === '福建省') {
        hasChild = true
      } else if (node.data.name === '广东省') {
        hasChild = false
      } else {
        hasChild = Math.random() > 0.5
      }
      // 添加子元素进内部
      setTimeout(() => {
        var data
        if (hasChild) {
          data = [{ name: '厦门市' }]
        } else {
          data = []
        }
        resolve(data)
      }, 500)
    },
    // 选中节点
    handleCheckChange(data, checked, indeterminate) {
      // data:原数据 / checked:选中状态 / indeterminate:原始选中状态
      console.log(data, checked, indeterminate)
    }
  }
}
</script>

✅懒加载自定义叶子节点

提前告知 Tree 某个节点是否为叶子节点,从而避免在叶子节点前渲染下拉按钮。

在这里插入图片描述

<template>
  <el-tree
    :props="defaultProps"
    lazy
    :load="loadNode"
    show-checkbox
  />
</template>

<script>
export default {
  data() {
    return {
      defaultProps: {
        label: 'name',
        children: 'zones',
        isLeaf: 'leaf'
      }
    }
  },
  methods: {
    // 加载子树数据
    loadNode(node, resolve) {
      // 往1级添加数据
      if (node.level === 0) return resolve([{ name: '福建省' }, { name: '广东省' }])
      // 第2级(最后1级)不再加载
      if (node.level > 1) return resolve([])
      // 添加子元素进内部
      setTimeout(() => {
        const data = [{ name: '厦门市', leaf: 'true' }]
        resolve(data)
      }, 500)
    }
  }
}
</script>

✅默认展开和默认选中

default-expanded-keys 设置默认展开的节点;
default-checked-keys 设置默认选中的节点。

注意:此时必须设置 node-key,其值为节点数据中的一个字段名,在整棵树中是唯一的。

<template>
  <el-tree
    :data="data"
    show-checkbox
    node-key="id"
    :default-expanded-keys="[2, 3]"
    :default-checked-keys="[5]"
  />
</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'
            }
          ]
        }
      ]
    }
  }
}
</script>

✅禁用状态

在每一项,添加 disabled: true,就可以实现了。

在这里插入图片描述

data: [
  {
    id: 1,
    label: '一级',
    children: [
      {
        id: 2,
        label: '二级',
        children: [
          {
            id: 3,
            label: '三级',
            disabled: true
          }
        ]
      }
    ]
  }
]

✅树节点的选择

<template>
  <div>
    <el-tree
      ref="tree"
      :data="data"
      show-checkbox
      default-expand-all
      node-key="id"
      highlight-current
    />

    <div class="buttons">
      <el-button @click="getCheckedNodes">通过 node 获取</el-button>
      <el-button @click="setCheckedNodes">通过 node 设置</el-button>
      <el-button @click="getCheckedKeys">通过 key 获取</el-button>
      <el-button @click="setCheckedKeys">通过 key 设置</el-button>
      <el-button @click="resetChecked">清空</el-button>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      data: [
        {
          id: 1,
          label: '一级',
          children: [
            {
              id: 2,
              label: '二级',
              children: [
                {
                  id: 3,
                  label: '三级'
                }
              ]
            }
          ]
        }
      ]
    }
  },
  methods: {
    /* ⭐ 基于节点数据(少用❗) */
    // 获取到选中的复选框的节点数据
    getCheckedNodes() {
      console.log(this.$refs.tree.getCheckedNodes())
    },
    // 根据节点数据回填复选框
    setCheckedNodes() {
      this.$refs.tree.setCheckedNodes([{ id: 2, label: '二级' }])
    },

    /* ⭐ 基于节点ID(常用👍) */
    // 获取到选中的复选框的节点ID
    getCheckedKeys() {
      // 输出id组成的数组,比如[1,2,3]
      console.log(this.$refs.tree.getCheckedKeys())
      // 如果只想获取一级和二级的节点key集合
      const allCheckedKeys = this.$refs.tree.getCheckedKeys()
      const filteredKeys = allCheckedKeys.filter(key => {
        // 判断是否是一级或二级节点
        const node = this.$refs.tree.getNode(key)
        return node.level === 1 || node.level === 2
      })
      console.log(filteredKeys) // 输出: [1, 2]
    },
    // 根据节点ID回填复选框
    setCheckedKeys() {
      this.$refs.tree.setCheckedKeys([3])
    },
    // 清空所有选中的状态
    resetChecked() {
      this.$refs.tree.setCheckedKeys([])
    }
  }
}
</script>

✅自定义节点内容

共两种方法

render-content

<template>
  <el-tree
    :data="data"
    show-checkbox
    node-key="id"
    default-expand-all
    :expand-on-click-node="false"
    :render-content="renderContent"
  />
</template>

<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))
    }
  },
  methods: {
    // 新增(在Children的最后面)
    append(data) {
      const newChild = { id: id++, label: 'test', 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)}
            >
              新增
            </el-button>
            <el-button
              size='mini'
              type='text'
              on-click={() => this.remove(node, data)}
            >
              删除
            </el-button>
          </span>
        </span>
      )
    }
  }
}
</script>

<style lang="scss">
// ❗这里不能使用scoped,不然样式不生效
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
</style>

scoped slot

<template>
  <el-tree
    :data="data"
    show-checkbox
    node-key="id"
    default-expand-all
    :expand-on-click-node="false"
  >
    <span slot-scope="{ node, data }" class="custom-tree-node">
      <span>{{ node.label }}</span>
      <span>
        <el-button type="text" size="mini" @click="() => append(data)">
          新增
        </el-button>
        <el-button type="text" size="mini" @click="() => remove(node, data)">
          删除
        </el-button>
      </span>
    </span>
  </el-tree>
</template>

<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))
    }
  },
  methods: {
    // 新增(在Children的最后面)
    append(data) {
      const newChild = { id: id++, label: 'test', 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)
    }
  }
}
</script>

<style lang="scss">
// ❗这里不能使用scoped,不然样式不生效
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
</style>

✅节点过滤

<template>
  <div>
    <el-input v-model="filterText" placeholder="输入关键字进行过滤" />

    <el-tree
      ref="tree"
      :data="data"
      default-expand-all
      :filter-node-method="filterNode"
    />
  </div>
</template>

<script>
export default {
  data() {
    return {
      filterText: '',
      data: [
        {
          id: 1,
          label: '一级 1',
          children: [
            {
              id: 2,
              label: '二级 1-1',
              children: [
                {
                  id: 3,
                  label: '三级 1-1-1'
                }
              ]
            }
          ]
        }
      ]
    }
  },
  watch: {
    // 过滤时调用Tree实例的filter方法
    filterText(val) {
      this.$refs.tree.filter(val)
    }
  },
  methods: {
    // 对树节点进行筛选
    filterNode(value, data) {
      // 如果输入为空,则全部显示,不进行过滤
      if (!value) return true
      // 否则,根据输入的内容进行过滤
      return data.label.indexOf(value) !== -1
    }
  }
}
</script>

✅手风琴模式

通过 accordion 属性可让 Tree 树形控件 变为手风琴模式。
手风琴模式

<el-tree accordion/>

✅可拖拽节点

通过 draggable 属性可让节点变为可拖拽。
在这里插入图片描述

<template>
  <el-tree
    :data="data"
    node-key="id"
    default-expand-all
    draggable
    :allow-drop="allowDrop"
    :allow-drag="allowDrag"
    @node-drag-start="handleDragStart"
    @node-drag-enter="handleDragEnter"
    @node-drag-leave="handleDragLeave"
    @node-drag-over="handleDragOver"
    @node-drag-end="handleDragEnd"
    @node-drop="handleDrop"
  />
</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'
                }
              ]
            }
          ]
        }
      ]
    }
  },
  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) {
      // type参数:'prev'、'inner'、'next'
      // 放置在目标节点`前`、插入至`目标`节点、放置在目标节点`后`
      if (dropNode.data.label === '二级 3-1') {
        // '二级 3-1'节点只能放置在目标节点的前后
        return type !== 'inner'
      } else {
        // 其它节点可任意放置
        return true
      }
    },
    // 判断节点能否被拖拽
    allowDrag(draggingNode) {
      // 当前'三级 3-2-2'节点不可拖拽
      return draggingNode.data.label.indexOf('三级 3-2-2') === -1
    }
  }
}
</script>
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
el-tree内使用el-select的目的是为了实现树形结构的多选功能。通过el-tree选择需要的节点并获取数据,然后将获取的数据关联到el-select并渲染输入框的内容。这样可以实现在el-tree中选择节点后,在el-select中显示选中的节点,并可以进行多选操作。具体实现的步骤如下: 1. 在el-select中设置v-model绑定一个数组,用于存储选中的节点数据。 2. 在el-tree中设置show-checkbox属性,以显示复选框。 3. 在el-tree的check-change事件中,通过this.$refs.tree.getCheckedNodes()方法获取选中的节点数据,并将其赋值给selectTree数组和value数组。 4. 在el-select的el-option中设置disabled属性,以禁用选项,因为选项的数据是通过el-tree获取的,而不是通过option。 5. 在el-select的remove-tag事件中,通过this.$refs.tree.getCheckedNodes()方法获取当前选中的节点数据,并将其从selectTree数组和value数组中移除。 6. 在el-select的clear事件中,将selectTree数组和value数组置空,并通过this.$refs.tree.setCheckedNodes(\[\])方法将el-tree中的选中状态清空。 通过以上步骤,就可以实现在el-tree内使用el-select,并实现树形结构的多选功能。 #### 引用[.reference_title] - *1* *2* *3* [el-select和el-tree结合使用-树形结构多选框](https://blog.csdn.net/s_9527_s/article/details/125320894)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Heisenberg504

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值