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


之前写了一篇用el-tree实现可选择树形表格的博客   最近再次有这种树形表格的需求,研究了下,发现用el-table本身支持的树形数据改造下也可以实现
两种方式都可以实现需求,这里只是多提供一种思路,至于选择哪一种方法,根据实际情况
用el-tree实现   优点: 1.不用处理数据层级关系, 2.选择时的互动效果比较好  3.多层级数据也适用   缺点: 1. 需要自己写表头样式, 额外的表格样式较多, 2.不能用表格的一些便利属性(排序, 筛选...)
用el-table实现   优点: 1.样式可以使用自带的,不用自定义表头,表格样式  2.可以无负担的使用表格的属性   缺点: 1.需要自己处理点击时父子联动效果  2.层级较多时处理数据将变得很复杂   代码地址: https://github.com/shengbid/vue-demo/tree/master/src/views/Table/treeTable 完成效果: 实现:       :indent="indent"          :tree-props="{children: 'childs'}">                                                                     v-if="scope.row.childs"            :indeterminate="scope.row.indeterminate"           v-model="scope.row.checked"            @change="changeRowSelect(scope.row)"          />                    v-else            v-model="scope.row.checked"            @change="changeRowSelect(scope.row)"          />                                                               详情               

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)
    }
  }
}