element的列表树形数据中添加复选框并增加render与slot支持

前言:

        对element的列表二次进行封装,让他能支持树形数据中添加复选框,并支持render与slot的使用。

实现效果:

 

实现步骤:

1、引入封装代码 checkTable

import checkTable from '@/views/pages/system/user/checkTable'
components:{
    checkTable
  },

2、页面调用,使用插槽,最大的还原element的写法

template内部:

<checkTable :tableData="tableData" :columns="columns">
      <el-table-column
        slot="date"
        label="日期"
        width="180">
        <template slot-scope="scope">
          <span>{
   
   { scope.row.date }}</span>
        </template>
      </el-table-column>
      <el-table-column
        slot="name"
        label="姓名"
        width="180">
        <template slot-scope="scope">
          <span>{
   
   { scope.row.name }}</span>
        </template>
      </el-table-column>
      <el-table-column
        slot="address"
        label="地址"
        width="180">
        <template slot-scope="scope">
          <span>{
   
   { scope.row.address }}</span>
        </template>
      </el-table-column>
    </checkTable>

data:
data(){
    return{
    //列表数据,带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 弄'
        }
      ],
        //表头
      columns:[
        {slot:'date'},
        {slot:'name'},
        {slot:'address'},
      ]

3、页面调用-js中定义

<checkTable :tableData="tableData" :columns="columns"></checkTable>

data:
data(){
    return{
    //列表数据,带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 弄'
        }
      ],
        //表头
      columns:[
        {
           prop:'name',
           title:'姓名',
           align:'center',
           width:150,
        },
        ...
      ]

封装源码:checkTable.vue

<template>
  <el-table
    ref="multipleTable"
    border
    :data="tableData"
    row-key="id"
    :default-expand-all="true"
    :tree-props="{hasChildren: 'hasChildren',children: 'children'}"
  >
    <el-table-column width="80">
      <template slot="header" slot-scope="scope">
        <el-checkbox
          v-model="allCheckout"
          style="padding-left: 10px"
          @change="checkAllFun()"
        />
      </template>
      <template slot-scope="scope">
        <el-checkbox
          v-model="scope.row.checks"
          style="padding-left: 10px"
          @change="checkChange(scope.row)"
        />
      </template>
    </el-table-column>
    <template v-for="(column, index) in columns">
      <!-- slot 添加自定义配置项 -->
      <slot v-if="column.slot" :name="column.slot" :tit='index'></slot>
      <!-- 默认渲染列-渲染每一列的汉字 -->
      <el-table-column
        v-else
        :prop="column.prop"
        :label="column.title"
        :align="column.align"
        :width="column.width"
        :show-overflow-tooltip="true">
        <template slot-scope="scope">
          <!--正常渲染-->
          <template v-if="!column.render">
            <template v-if="column.formatter">
              <span v-html="column.formatter(scope.row, column)"></span>
            </template>
            <template v-else>
              <span>{
   
   {scope.row[column.prop]}}</span>
            </template>
          </template>
          <!--render函数-->
          <template v-else>
            <expandDom :column="column" :row="scope.row" :render="column.render" :index="index"></expandDom>
          </template>
        </template>
      </el-table-column>
    </template>



  </el-table>

</template>

<script>
/**
 * @封装的复选框加列表expend展开功能列表
 * @createTime 2023.6
 * @auth ry
 * */
export default {
  name: "checkTable.vue",
  props:{
    // 表格数据
    tableData:{
      type: Array,
      deep:true,
      immediate:true,
      default:()=>[]

    },
    //表头
    columns: {
      type:Array,
      default:()=>[]
    },
    tableClass: {
      type: String,
      default: 'checkTable'
    },
  },
  components: {
    /**
     * render函数渲染组件
     * */
    expandDom: {
      functional: true,
      props: {
        row: Object,
        render: Function,
        index: Number,
        column: {
          type: Object,
          default: null
        }
      },
      render: (h, ctx) => {
        const params = {
          row: ctx.props.row,
          index: ctx.props.index
        }
        if (ctx.props.column) params.column = ctx.props.column
        return ctx.props.render(h, params)
      }
    }
  },
  data(){
    return{
      // tableData: [],
      mapData: [],
      allCheckout: false, //全选
    }
  },
  methods:{
    // 获取当前选中的数据
    getNowSelData(){
      let selData = []
      this.tableData.forEach(item=>{
        // 一级无子级
        if(item.checks && !item.children){
          selData.push(item)
        }
        // 一级有子级
        if(item.checks && item.children && item.children.length){
          selData.push(item)
          selData = selData.concat(item.children)
        }
        // 二级无子级
        if(!item.checks && item.children && item.children.length){
          item.children.forEach(two=>{
            if(two.checks){
              selData.push(two)
            }
          })
        }
      })
      return selData
    },
    // 获取当前选中的数据-只有一级数据
    getNowSelDataOneType(){
      let selData = []
      this.tableData.forEach(item=> {
        // 一级无子级
        if (item.checks) {
          selData.push(item)
        }
      })
      return selData
    },
    // 总全选点击事件
    checkAllFun() {
      this.$refs.multipleTable.data.forEach(items => {
        this.$set(items, "checks", this.allCheckout);
        if (items.children) {
          items.children.forEach((item) => {
            this.$set(item, "checks", this.allCheckout);
          });
        }
      });
    },
    //插槽复选框逻辑
    checkChange(row) {
      // expend 父级复选框
      if (row.children) {
        if (row.checks) {
          row.children.map((item) => {
            this.$set(item, "checks", true);
          });
          this.$set(row, "checks", true);
          // this.mag = true;
        } else {
          row.children.map((item) => {
            this.$set(item, "checks", false);
          });
          this.$set(row, "checks", false);
        }
        return
      }
      // 子带父
      this.mapData = []
      // 一级无子级的,或者二级无子级的
      this.$set(row, "checks", row.checks)
      const findTypeArr = this.tableData.filter(v=>v.id == row.id)
      let jb_type = ''
      if(findTypeArr.length>0){
        jb_type = '1'
      }else{
        jb_type = '2'
      }
      // 一级的操作
      if(jb_type == '1' && !row.checks){
        this.allCheckout = false
      }
      if(jb_type == '1' && row.checks){
        this.allCheckSetFun()
      }
      // 二级操作
      if(jb_type == '2' && !row.checks){
        this.allCheckout = false
        this.tableData.forEach(one => {
          if (one.children && one.children.length > 0) {
            one.children.forEach(two => {
              if (two.id == row.id) {
                this.$set(one, "checks", false)
              }
            })
          }
        })
      }
      if(jb_type == '2' && row.checks){
        this.tableData.forEach(one => {
          if (one.children && one.children.length > 0) {
            one.children.forEach(two => {
              if (two.id == row.id) {
                let twoSelArr = one.children.filter(v=>v.checks)
                if(twoSelArr.length == one.children.length){
                  this.$set(one, "checks", true)
                }else{
                  this.$set(one, "checks", false)
                }
              }
            })
          }
        })
        this.allCheckSetFun()
      }

    },
    // 修改外部总勾选
    allCheckSetFun(){
      let oneSelArr = this.tableData.filter(v=>v.checks)
      if(oneSelArr.length == this.tableData.length){
        this.allCheckout = true
      }else{
        this.allCheckout = false
      }
    },

  }
}
</script>

<style type="scss" scoped>
</style>

猜你喜欢

转载自blog.csdn.net/weixin_44727080/article/details/131113345