el-tree实现父子节点不关联,包括禁用节点,父亲节点全选,父亲节点反选和总体全选反选,可以直接拿去用

这篇文章展示了如何在Vue.js中使用el-tree组件实现父子节点不关联的全选和取消全选功能。代码示例中包含了全选按钮的逻辑处理,以及在有禁用节点存在时,全选状态的判断。提供了完整的模板、脚本和样式代码。
摘要由CSDN通过智能技术生成

1.父子不交互效果实现:

(1)节点的+标志是全选当前节点及子节点按钮

(2)修改标志是取消选中 前节点及子节点按钮

 

2.当前页面点击全选按钮效果:(犹豫包括一个未选中禁用节点,所以全选按钮没勾选)

 3.取消全选按钮效果:同上(犹豫包括一个未选中的禁用的节点)

 4.下面是全部代码,小伙伴们可以细心观看,直接拿过去用也是可以的,不过数据是写死的你们根据自己情况修改。

<template>
  <div>
    <el-checkbox v-model="checkecd" @change="checkedAll">
      全部
    </el-checkbox>
    <el-tree
      ref="tree"
      :data="treeData"
      show-checkbox
      node-key="id"
      :default-checked-keys="[1]"
      :default-expand-all="true"
      check-strictly //***声明该属性可以父子节点不关联***
      @check-change="checkChange" //树节点发生改变触发事件
    >
      <div slot-scope="{ node, data }">
        <template>
          <!-- 名称: 新增节点增加class(is-new) -->
          <span>
            {{ node.label }}
          </span>

          <!-- 按钮 -->
          <span>
            <!-- 全选 -->
            <el-button
              icon="el-icon-plus"
              title="全选"
              size="mini"
              circle
              type="primary"
              @click.stop="allcheck(data)"
              v-if="data.children"
            ></el-button>

            <!-- 取消全选 -->
            <el-button
              icon="el-icon-edit"
              title="取消全选"
              size="mini"
              circle
              type="info"
              @click.stop="caclecheck(data)"
              v-if="data.children"
            ></el-button>
          </span>
        </template>
      </div>
    </el-tree>
  </div>
</template>

<script>
export default {
  data() {
    return {
      treeData: [
        {
          id: 1,
          label: '一级 1',
          disabled: true,
          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',
            },
          ],
        },
      ], // 树形数据
      levelData: [], // 拉平后的treeData
      checkecd: false, // 全选状态
    }
  },
  created() {
    this.getLevelData()//拉平数据
    this.checkChange()//先检测一遍当前全选了没
  },
  methods: {
    allcheck(data) {
      //子节点全选
      console.log(data)
      this.dgTree([data], 1) //调用递归(2代表子节点全部取消选中) **[data]是因为当前父亲最外层是{}不是数组,所有要包一层[]不然会报错
    },
    caclecheck(data) {
      //子节点取消全选
      this.dgTree([data], 2) //调用递归(2代表子节点全部取消选中)
    },
    dgTree(data, type) {
      //递归当前选中和取消按钮的数据
      data.forEach((item) => {
        if (type == 1) {
          //type==1选中
          if (item.disabled != true) {
            //如果当前节点不禁用,选中
            this.$refs.tree.setChecked(item, true)
          }
        } else {
          if (item.disabled != true) {
            //如果当前节点不禁用,不选中
            this.$refs.tree.setChecked(item, false)
          }
        }
        if (item.children) {
          this.dgTree(item.children, type)
        }
      })
    },

    // 获取拉平后的数据
    getLevelData() {
      let cloneData = JSON.parse(JSON.stringify(this.treeData))
      this.levelData = this.recursion(cloneData)
    },
    // 全选、反选
    checkedAll() {
      if (this.checkecd) {
        this.dgTree(this.treeData, 1)
      } else {
        this.dgTree(this.treeData, 2)
      }
      this.checkChange() //再次检测是否全选了
    },
    // 树结构勾选
    checkChange(item, isChecked) {
      // 获取勾选的数据
      let checkNode = this.$refs.tree.getCheckedKeys() //获取当前所有选中的节点
      // 如果勾选数量===拉平后的treeData的数量 那么相当于全选 反之则是反选
      // 如果小于数组数量则是半选
      if (checkNode.length === this.levelData.length) {
        //如果所有选中节点的长度==拉平树的数量,那么当前是全选
        this.checkecd = true
      } else if (checkNode.length === 0) {
        //如果所有选中节点的长度==0,那么当前未全选
        this.checkecd = false
      } else if (checkNode.length < this.levelData.length) {
        //如果所有选中节点的长度==小于拉平的长度,那么当前未全选
        this.checkecd = false
      }
    },
    // 递归调用
    recursion(arr) {
      //递归平铺树形结构来获取当前树节点长度多少
      return [].concat(
        ...arr.map((item) => {
          if (item.children) {
            let arr = [].concat(item, ...this.recursion(item.children))
            delete item.children
            return arr
          }
          return [].concat(item)
        }),
      )
    },
  },
}
</script>
<style>
.el-button--mini.is-circle {
  padding: 0.03rem !important;
}
</style>

最后感觉对自己有用可以点个赞,本人也是个菜鸟,给个鼓励谢谢大家!

实现全选反选功能,需要在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中的数据是静态的,所以需要自己维护节点父子关系。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值