Tree-V2 实现 全选、反选

使用场景:

需要一个 tree 树形结构体,但是采用 普通的 tree ,在数据量大的时候 会造成 tree 渲染的压力,尤其是在勾选的时候。

element ui plus 中 引入了 “Tree V2 虚拟化树形控件” 具体的内容可以 参考这里

<el-button @click="selectAll" size="small" type="primary">全选</el-button>
<el-button @click="deselectAll" size="small" type="primary">反选</el-button>

      <div style="margin-top: 15px">
        <el-input
            v-model="query"
            style="width: 240px;"
            placeholder="请输入关键字进行检索"
            @input="onQueryChanged"
            size="small"
        />
        <el-tree-v2
            ref="treeV"
            style="max-width: 800px"
            :data="data"
            :props="props"
            show-checkbox
            :filter-method="filterMethod"
            :height="400"
        >
          <template #default="{ node, data }">
            <!-- 自定义节点内容 -->

            <el-popover
                placement="right"
                :width="200"
                trigger="hover"
                :content="data.label"
                :effect="'dark'"
                :show-after="500"
            >
              <template #reference>
                <span>{{ data.label }}</span>
              </template>
            </el-popover>
          </template>
        </el-tree-v2>

其中

getCheckedNodes() 返回 获取所有勾选的 id

setCheckedKeys() 设置勾选的id

const setAllNodeChecked = (checked) => {
  console.log(treeV.value.getCheckedNodes(), 'treeV.value')
  console.log(treeV.value, 'treeV.value')
  if (treeV.value) {
    // 全选
    const nodes = treeV.value.getCheckedNodes()
    if (checked) {
      const checkTargetArray = nodes.filter(item => item.level === 1).length;
      if (checkTargetArray === data.value.length) {
        treeV.value.setCheckedKeys([])
      } else {
        // 选中的 key 的数组
        const allKeys = data.value.map(node => node.id);
        treeV.value.setCheckedKeys(allKeys);
      }
    } else {
      // 过滤出未选中的数组
      const unCheckedArray = differenceBy(data.value, nodes, 'id')
      // 选中的 key 的数组
      const allKeys = unCheckedArray.map(node => node.id);
      // 设置所有节点为选中状态
      treeV.value.setCheckedKeys(allKeys);
    }
  }
}

// arr1 - arr2 的差集
function differenceBy(arr1, arr2, prop) {
  const set = new Set(arr2.map(item => item[prop]));
  console.log(set, 'set')
  return arr1.filter(item => !set.has(item[prop]));
}

const setCheckedRecursive = (node, checked) => {
  node.checked = checked;
  console.log(node.checked, 'node.checked')
  if (node.children) {
    node.children.forEach(child => {
      setCheckedRecursive(child, checked);
    });
  }
}

// 全选
const selectAll = () => {
  setAllNodeChecked(true);
}
// 反选
const deselectAll = () => {
  setAllNodeChecked(false);
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现全选功能,需要在el-tree中使用el-checkbox组件,并通过一些JavaScript代码来监听中状态的变化。 以下是一个实现全选功能的示例代码: ```html <el-tree :data="treeData" node-key="id" show-checkbox @check-change="handleCheckChange"> <template slot-scope="{ node, data }"> <span>{{ node.label }}</span> <el-checkbox v-model="data.checked" :indeterminate="data.indeterminate" @change="handleCheckChange"></el-checkbox> </template> </el-tree> ``` 在上述代码中,el-tree组件设置了show-checkbox属性,表示显示复框;使用了el-checkbox组件来实现框的功能。 同时,在el-checkbox组件中,绑定了v-model来实现数据的双向绑定,以及@change事件来监听复框状态的变化。 在JavaScript中,需要实现一个handleCheckChange方法来处理复框状态的变化,具体实现如下: ```js methods: { handleCheckChange(nodeData) { if (nodeData.checked) { // 中节点 this.checkNode(nodeData, true); } else { // 取消中节点 this.checkNode(nodeData, false); } }, checkNode(nodeData, checked) { nodeData.checked = checked; if (nodeData.children && nodeData.children.length > 0) { // 处理子节点 nodeData.children.forEach(childNode => { this.checkNode(childNode, checked); }); } const parentNode = this.getParentNode(nodeData); if (parentNode) { // 更新父节点状态 this.updateParentNode(parentNode); } }, getParentNode(nodeData) { let parentNode = null; let currentNode = nodeData; while (currentNode && !parentNode) { currentNode = currentNode.parent; if (currentNode && currentNode.level === 0) { parentNode = currentNode.data; } } return parentNode; }, updateParentNode(nodeData) { let checkedCount = 0; let indeterminateCount = 0; nodeData.children.forEach(childNode => { if (childNode.checked) { checkedCount++; } else if (childNode.indeterminate) { indeterminateCount++; } }); if (checkedCount === nodeData.children.length) { // 所有子节点都中了 nodeData.checked = true; nodeData.indeterminate = false; } else if (checkedCount === 0) { // 所有子节点都没有中 nodeData.checked = false; nodeData.indeterminate = false; } else { // 部分子节点中 nodeData.checked = false; nodeData.indeterminate = true; } const parentNode = this.getParentNode(nodeData); if (parentNode) { // 更新父节点状态 this.updateParentNode(parentNode); } } } ``` 在上述代码中,handleCheckChange方法用来处理复框状态变化的逻辑,checkNode方法用来递归处理子节点的状态,updateParentNode方法用来更新父节点的状态。由于el-tree中的数据是静态的,所以需要自己维护节点的父子关系。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值