element el-table实现树形可选择表格

之前写了一篇用el-tree实现可选择树形表格的博客
 
最近再次有这种树形表格的需求,研究了下,发现用el-table本身支持的树形数据改造下也可以实现

两种方式都可以实现需求,这里只是多提供一种思路,至于选择哪一种方法,根据实际情况

用el-tree实现
  优点: 1.不用处理数据层级关系, 2.选择时的互动效果比较好  3.多层级数据也适用
  缺点: 1. 需要自己写表头样式, 额外的表格样式较多, 2.不能用表格的一些便利属性(排序, 筛选...)

用el-table实现
  优点: 1.样式可以使用自带的,不用自定义表头,表格样式  2.可以无负担的使用表格的属性
  缺点: 1.需要自己处理点击时父子联动效果  2.层级较多时处理数据将变得很复杂
 
完成效果:

 

实现:
<el-table
    :data="tableData2"
    style="width: 100%;margin-bottom: 20px;"
    row-key="id"
    border
    default-expand-all
    <!-- 子级缩进距离 -->
    :indent="indent"
    <!-- 如果返回的数据,子级不是children,需要在这里指定 -->
    :tree-props="{children: 'childs'}">
    <el-table-column
      width="75">
      <!-- 表格头的选择框 -->
      <template slot="header" slot-scope="scope">
        <el-checkbox v-model="checkedAll" @change="changeAllSelect" />
      </template>
      <!-- 表格行的选择框, 如果是父级,设置一个indeterminate显示未全选的样式 -->
      <template slot-scope="scope">
        <el-checkbox 
          v-if="scope.row.childs" 
          :indeterminate="scope.row.indeterminate"
          v-model="scope.row.checked" 
          @change="changeRowSelect(scope.row)" 
        />
        <el-checkbox 
          v-else 
          v-model="scope.row.checked" 
          @change="changeRowSelect(scope.row)" 
        />
      </template>
    </el-table-column>
    <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-column label="操作" width="80">
      <template slot-scope="scope">
        <el-button
          size="mini"
          >详情</el-button>
      </template>
    </el-table-column>
  </el-table>

checkbox需要自己写,不能使用el-table的type="selection",伸缩图标位置不对

 
有一个样式要注意一下, 可以使用indent设置子级缩进距离,使层级看起来更明显,默认是16px

 

js:

export default {
  template,

  data () {
    return {
      tableData2: [],
      checkedAll: false, // 是否全选
    }
  },

  created() {
    this.getTree()
  },
  // 方法集合
  methods: {
    // 获取表格数据
    async getTree () {
      const { data } = await getTreeData()
      console.log(data)
      this.tableData2 = data
    },

    // 选择表格(全选)
    changeAllSelect (val) {
      // console.log(val)
      const loop = (data) => {
        data.forEach(item => {
          item.checked = val
          if ('indeterminate' in item) {
            item.indeterminate = false
          }
          if (item.childs) {
            loop(item.childs)
          }
        })
      }
      loop(this.tableData2)
    },

    // 选择表格(表格行选择)
    changeRowSelect (val) {
      // console.log(val)
      if (!isEmpty(val.childs)) {
        val.childs.forEach(ss => {
          ss.checked = val.checked
        })
      } else {
        let checkedLeg = 0
        this.tableData2.some(item => {
          if (item.id === val.parentId) {
            // 获取当前父级下子级选中条数
            const leg = item.childs.length
            checkedLeg = item.childs.filter(ss => ss.checked).length
            // 根据条数改变父级的indeterminate和checked
            if (checkedLeg === 0) {
              item.indeterminate = false
              item.checked = false
            } else if (checkedLeg < leg) {
              item.indeterminate = true
              item.checked = false
            } else if (checkedLeg === leg) {
              item.indeterminate = false
              item.checked = true
            }

            return
          }
        })
        // console.log(this.tableData2)
      }
      // 判断是否全部选择了,改变全选框的样式
      let flag = true
      this.tableData2.some(item => {
        if (!item.checked) {
          flag = false
          return
        }
      })
      this.checkedAll = flag
    },

    // 点击提交选中的表格
    handleSelectTable () {
      const selectedIds = []
      const loop = (data) => {
        data.forEach(item => {
          if (item.checked || item.indeterminate) {
            selectedIds.push(item.id)
            if (item.childs) {
              loop(item.childs)
            }
          }
        })
      }
      loop(this.tableData2)
      console.log(selectedIds)
    }
  }
}

 

posted @ 2022-03-17 17:03  潇湘羽西  阅读(6425)  评论(1编辑  收藏  举报