element ui 树形-懒加载-表格-多选 勾选问题

element ui树形表格如下:

它的数据格式为:使用children字段来存放子级数据

      tableData: [
        {
          id: 1,
          date: "2016-05-02",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1518 弄",
        },
        {
          id: 2,
          date: "2016-05-04",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1517 弄",
        },
        {
          id: 3,
          date: "2016-05-01",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1519 弄",
          children: [
            {
              id: 31,
              date: "2016-05-01",
              name: "王小虎",
              address: "上海市普陀区金沙江路 1519 弄",
            },
            {
              id: 32,
              date: "2016-05-01",
              name: "王小虎",
              address: "上海市普陀区金沙江路 1519 弄",
            },
          ],
        },
        {
          id: 4,
          date: "2016-05-03",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1516 弄",
        },
      ],

element ui 树形&懒加载 表格如下:

默认是不请求子级数据的,当点击下拉icon时再发起请求

 完整代码:

DOM:  需注意以下属性

        row-key="id"

        lazy

        :load="load"

        :tree-props="{

          children: 'children',

          hasChildren: 'hasChildren',

        }"

  <el-table
    :data="tableData1"
    style="width: 100%"
    row-key="id"
    border
    lazy
    :load="load"
    :tree-props="{children: 'children', hasChildren: 'hasChildren'}">
    <el-table-column
      prop="date"
      label="日期"
      width="180">
    </el-table-column>
    <el-table-column
      prop="name"
      label="姓名"
      width="180">
    </el-table-column>
    <el-table-column
      prop="address"
      label="地址">
    </el-table-column>
  </el-table>

数据:就是普通的数组,没有子级数据的概念

      tableData1: [
        {
          id: 1,
          date: "2016-05-02",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1518 弄",
        },
        {
          id: 2,
          date: "2016-05-04",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1517 弄",
        },
        {
          id: 3,
          date: "2016-05-01",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1519 弄",
          hasChildren: true,
        },
        {
          id: 4,
          date: "2016-05-03",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1516 弄",
        },
      ],

懒加载事件:

    load(tree, treeNode, resolve) {
     // 这里发请求,请求当前点击的子级数据data,然后交给resolve处理,就可以正确展示子级数据
      setTimeout(() => {
        resolve(data);
      }, 300);
    },

发现树形懒加载多选表格有两个问题:

1、勾选父级时子级不会勾选上

一般我们实现表格多选功能是这样的:这里不再使用这种方式

     <el-table-column
      type="selection"
      width="55">
    </el-table-column>

 第一步:需要我们手动写个勾选表头和勾选列

        <el-table-column type="test" align="left" width="55">
          <!-- 表头的全选勾选框,indeterminate:是否半选状态,handleCheckAllDetail:全选事件 -->
          <template slot="header" slot-scope="scope">
            <el-checkbox
              :indeterminate="isIndeterminate"
              v-model="checkAllDetail"
              @change="handleCheckAllDetail"
            ></el-checkbox>
          </template>
          <!-- 表格数据列单行勾选框,使用checked属性决定是否勾选,单行勾选事件 -->
          <template slot-scope="scope">
            <el-checkbox
              v-model="scope.row.checked"
              @change="handleCheckDetail(scope.row, $event)"
            ></el-checkbox>
          </template>
        </el-table-column>

第二步: 定义数据

    checkAllDetail: false,
    isIndeterminate: false,

第三步:编写handleCheckAllDetail、handleCheckDetail函数,

每次勾选时要做的事:

处理全选、半选状态;

用个数组处理勾选行的数据,勾选时将数据存起来,取消勾选时将数据删除;

若勾选父级时,将子级的数据也全部勾选;取消勾选反之;

若勾选子级时,也要计算父级是否应该勾选上;

第四步:点击下拉icon时也要数据子级数据的勾选状态

这里涉及到一个很重要的问题:如何拿到子级数据:先给表格绑定ref属性

this.$refs.mulTable.store.states.lazyTreeNodeMap这个可以取到所有展开的子级数据

数据格式为:{父级id1: [{子数据1}, {子数据2}],  父级id2: [{子数据}] }

 举个例子:当勾选单个数据时如何处理

 // 单条数据的勾选操作
    handleCheckDetail(row, val) {
      // 如果勾选的是子级数据:那么要计算子级决定父级勾选状态
      if (row.parent) {
        let parentId = row.parent; //父级id
        let loadChildData = this.$refs.mulTable.store.states.lazyTreeNodeMap; // 所有展开项的懒加载数据
        let parentItem = loadChildData[parentId]; //当前父级下的所有子数据
        // 判断当前下的所有子数据是否全部勾选上了
        let checked = parentItem?.every(function (currentValue, index, arr) {
          return currentValue.checked;
        });
        // 设置父级数据的勾选状态
        for (let i = 0; i < this.list.length; i++) {
          if (this.list[i].id === parentId) {
            this.$set(this.list[i], "checked", checked);
          }
        }
        // 勾选则将id添加进去,否则删除id【selectArrIds是用来存放勾选数据的id的数组】
        if (checked) {
          this.selectArrIds.push(parentId);
        } else {
          let index = this.selectArrIds.indexOf(parentId);
          if (index !== -1) {
            this.selectArrIds.splice(index, 1);
          }
        }
      } else {
        // 如果当前点击的是父级数据:那么父级决定子级状态
        let loadChildData = this.$refs.mulTable.store.states.lazyTreeNodeMap; // 所有展开项的懒加载数据
        let datas = loadChildData[row.id]; //当前父级下的所有子数据
        // 将父级的勾选状态同步给子级
        datas?.forEach((item) => {
          this.$set(item, "checked", val);
        });
        // 勾选则将id添加进去,否则删除id【selectArrIds是用来存放勾选数据的id的数组】
        if (val) {
          this.selectArrIds.push(row.id);
        } else {
          let index = this.selectArrIds.indexOf(row.id);
          if (index !== -1) {
            this.selectArrIds.splice(index, 1);
          }
        }
      }
      // 计算半选和全选状态
      let totalCount = this.list.length;
      this.checkAllDetail =
        totalCount === this.selectArrIds.length ? true : false;
      this.isIndeterminate =
        this.selectArrIds.length > 0 && this.selectArrIds.length < totalCount;
    },

 当勾选全选checkbox时如何处理

    handleCheckAllDetail(val) {
      this.isIndeterminate = false;
      let setIds = [];
      this.list.forEach((item, index) => {
        if (
          val &&
          this.selectArrIds.indexOf(item.id) === -1
        ) {
          setIds.push(item.id);
        }
      });
      if (val) {
        this.selectArrIds = setIds;
      } else {
        this.selectArrIds = [];
      }
      // 若有展开项,则将子级也勾选上
      this.setChildCheck(val);
    },

 setChildCheck方法:

    // 设置子级的数据勾选状态
    setChildCheck(val) {
      let loadChildData = this.$refs.mulTable.store.states.lazyTreeNodeMap;
      if (Object.keys(loadChildData).length > 0) {
        let keys = [];
        for (let key in loadChildData) {
          keys.push(key);
        }
        for (let i = 0; i < keys.length; i++) {
          let datas = loadChildData[keys[i]];
          datas?.forEach((item) => {
            // 按父级的勾选状态去控制子级的勾选状态
            let isChecked;
            for (let i = 0; i < this.list.length; i++) {
              if (this.list[i].id === item.parent) {
                isChecked = this.list[i].checked;
              }
            }
            this.$set(item, "checked", isChecked);
          });
        }
      }
    },

效果如下:

element ui懒加载树形表格-勾选

2、对子级数据进行删除、修改、添加操作时,不会更新子级数据

这个问题目前还没实现,但是估计也是通过this.$refs.mulTable.store.states.lazyTreeNodeMap处理数据,稍后更新~~

PS:后来发现了另外一个非常棒的UI库,可以考虑使用~~

vxe-table v4

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
Element Plus的Tree Table组件是一个功能强大的工具,用于展示层次结构的数据,并支持多选功能。在Element Plus中,你可以使用`el-tree`组件来实现树形表格,其中包含选项卡式或多列的多选模式。以下是基本步骤: 1. **引入组件**:首先,在你的Vue项目中引入`ElementPlus`的Tree Table组件,通常通过`import { ElTree } from 'element-plus'`。 2. **配置数据**:定义一个树形数据结构,每个节点可能包含`label`(标签)、`children`(子节点数组)和一个布尔属性`checkable`(可选,表示是否可以被选择)。 3. **设置选中状态**:在节点对象上添加`selected`属性来控制当前节点是否被选中。你可以在`<el-tree>`组件的`props`中设置默认的选中状态或提供一个方法来处理选中/取消选中事件。 4. **多选功能**:在`<el-tree>`组件中启用多选,通常通过设置`default-checked-keys`属性来初始化选中的节点,或者使用`@selection-change`事件监听用户的选择变化。 ```html <template> <el-tree :data="treeData" :props="treeProps" :default-checked-keys="selectedKeys" @selection-change="handleSelectionChange" :check-strictly="true" <!-- 如果不需要递归选择,可以关闭 --> ></el-tree> </template> <script> export default { data() { return { treeData: ..., selectedKeys: [], // 初始化的选中节点ID数组 treeProps: { children: 'children', label: 'name', // 树形节点的显示文本 disabled: 'disabled', // 如果有的节点不可选择 }, }; }, methods: { handleSelectionChange(newKeys) { this.selectedKeys = newKeys; // 这里可以对新选中的节点做进一步操作 }, }, }; </script> ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值