目录

实现思路

主要代码

1.子组件代码(trendsTable.vue)

2.父组件-引用此组件主要代码

总结



实现思路

基于vue+elementUI-el-table+less实现表格列的隐藏与显示-之前版本是所有的列都可以进行隐藏或者显示,依据的判断条件是数组下标。此次更新版本是部分可以隐藏与显示,判断依据是此列的prop属性。

将表格展示+分页+显示/隐藏列  组件化,其中利用slot动态展示不同的表格数据,父组件引用此组件传递相应切必须的参数,当分页或显示/隐藏列动态变化时将数据再返回父组件,父组件中的列根据回传的数据利用v-if实现列的显示与隐藏  

在想要隐藏的列上加上class-name="column_visible" 并结合v-if=columnHideList[prop] 实现


主要代码

1.子组件代码(trendsTable.vue)

代码如下(示例):

<!-- create by crystalSong 分页+table+动态设置表格列的隐藏与显示 -->
<template>
  <div class="trends_container">
    <div class="table_container">
      <el-table
        ref="trendsTable"
        :data="tableList"
        fit
        stripe
        style="width: 100%"
        border
        :highlight-current-row="obj.hcrow"
        @selection-change="handleSelectionChange"
        @select="handleSelect"
        @select-all="handleSelectAll"
        @cell-mouse-enter="handleCellMouseEnter"
        @cell-mouse-leave="handleCellMouseLeave"
      >
        <slot />
      </el-table>
    </div>
    <div class="pagination_trends_wrap">
      <div class="trends_oprt_wrap">
        <el-popover placement="top-start" width="280" trigger="click">
          <div class="trends_btn_wrap">
            <el-checkbox-group v-model="visibleList" size="small">
              <el-checkbox
                v-for="(col, index) in columnList"
                :key="index"
                :label="col.label"
                border
                @change="visibleListChange(col,index,$event)"
              >{{ col.value }}</el-checkbox>
            </el-checkbox-group>
          </div>
          <el-button slot="reference" size="small">隐藏/显示列</el-button>
        </el-popover>
      </div>
      <div v-if="total > 0" class="pagination_wrap">
        <template>
          <el-pagination
            style="text-align: right;"
            :current-page.sync="currentPage"
            :page-sizes="[10,25,50,100]"
            :page-size.sync="currentSize"
            layout="total, sizes, prev, pager, next, jumper"
            :total="total"
            background
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </template>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'TrendsTable',
  components: {},
  props: {
    tableList: {
      type: Array,
      require: true,
      default: _ => []
    },
    hideColumnIndexs: {
      type: Array,
      default: _ => []
    },
    pageSize: {
      type: Number,
      default: 10
    },
    pageNumber: {
      type: Number,
      default: 1
    },
    total: {
      required: true,
      type: Number,
      default: 0
    },
    obj: {
      type: Object,
      default: () => {
        return {
          hcrow: false
        }
      }
    }
  },
  data() {
    return {
      visibleList: [], // 显示/隐藏列的选中下标数据集合
      columnList: [], // 表格所有列名称数据列表
      curHideList: {} // 动态更改的
    }
  },
  computed: {
    currentPage: {
      get() {
        return this.pageNumber
      },
      set(val) {
        this.$emit('update:pageNumber', val)
      }
    },
    currentSize: {
      get() {
        return this.pageSize
      },
      set(val) {
        this.$emit('update:pageSize', val)
      }
    }
  },
  watch: {},
  created() {

  },
  mounted() {
    const _this = this
    this.curHideList = {}
    this.$refs.trendsTable.$children.forEach((obj, index) => {
      if (obj.type) {
        // 根据类名定义动态列
        if (obj.className && obj.className.indexOf('column_visible') !== -1) {obj.className.indexOf('column_visible'))
          _this.columnList.push(
            {
              'label': index,
              'value': obj.type === 'selection' ? '选择' : obj.label,
              'columnId': obj.columnId,
              'prop': obj.prop
            }
          )
          this.curHideList[obj.prop] = true
          // _this.visibleList.push(index)
        }
      }
    })
    _this.$emit('getHideColist', this.curHideList)
  },
  methods: {
    // handleSizeChange
    handleSizeChange(val) {
      // console.log(`每页 ${val} 条`);
      this.$emit('pagination', { pageNumber: 1, pageSize: val })
    },
    // handleCurrentChange
    handleCurrentChange(val) {
      // console.log(`当前页码 ${val} `);
      this.$emit('pagination', { pageNumber: val, pageSize: this.currentSize })
    },
    visibleListChange(col, index, e) {
      if (e) {
        // 选中
        // this.curHideList[col.prop] = false
        this.$set(this.curHideList, col.prop, false)
      } else {
        // this.curHideList[col.prop] = true
        this.$set(this.curHideList, col.prop, true)
      }
      this.$emit('getHideColist', this.curHideList)
    },
    // 当选择项发生变化时会触发该事件
    handleSelectionChange(selection) {
      this.$emit('selection-change', selection)
    },
    // 当用户手动勾选数据行的 Checkbox 时触发的事件
    handleSelect(selection) {
      this.$emit('select', selection)
    },
    // 当用户手动勾选全选 Checkbox 时触发的事件
    handleSelectAll(selection) {
      this.$emit('select-all', selection)
    },
    // /当单元格 hover 进入时会触发该事件
    handleCellMouseEnter(row, column, cell, event) {
      this.$emit('cell-mouse-enter', 	row, column, cell, event)
    },
    // 当单元格 hover 退出时会触发该事件
    handleCellMouseLeave(row, column, cell, event) {
      this.$emit('cell-mouse-leave', row, column, cell, event)
    },
    // cell-click	当某个单元格被点击时会触发该事件	row, column, cell, event
    handleCellClick(row, column, cell, event) {
      this.$emit('cell-click', row, column, cell, event)
    },
    //  cell-dblclick	当某个单元格被双击击时会触发该事件	row, column, cell, event
    handleCellDbClick(row, column, cell, event) {
      this.$emit('cell-dblclick', row, column, cell, event)
    },
    // 某一行被点击
    handleRowClick(row, column, event) {
      this.$emit('row-click', row, column, event)
    },
    // row-dblclick	当某一行被双击时会触发该事件	row, column, event
    handleRowDbClick(row, column, event) {
      this.$emit('row-dblclick', row, column, event)
    },
    // row-contextmenu	当某一行被鼠标右键点击时会触发该事件	row, column, event
    handleRowContextmenu(row, column, event) {
      this.$emit('row-contextmenu', row, column, event)
    },
    // header-click	当某一列的表头被点击时会触发该事件	column, event
    handleHeaderClick(column, event) {
      this.$emit('header-click', column, event)
    },
    //  header-contextmenu	当某一列的表头被鼠标右键点击时触发该事件	column, event
    handleHeaderContextmenu(column, event) {
      this.$emit('header-contextmenu', column, event)
    },
    // sort-change	当表格的排序条件发生变化的时候会触发该事件	{ column, prop, order }
    handleSortChange(column, prop, order) {
      this.$emit('sort-change', column, prop, order)
    },
    // current-change	当表格的当前行发生变化的时候会触发该事件,
    // 如果要高亮当前行,请打开表格的 highlight-current-row 属性	currentRow, oldCurrentRow
    handleTableCurrentChange(currentRow, oldCurrentRow) {
      this.$emit('current-change', currentRow, oldCurrentRow)
    }

  }
}
</script>
<style lang='scss' scoped>
    .trends_container{
        .pagination_trends_wrap{
            margin: 20px 0;
            position: relative;
        }
        .trends_oprt_wrap{
            display: inline-block;
            vertical-align: top;
            width: 100px;
        }
        .pagination_wrap{
            display: inline-block;
            vertical-align: top;
            width: calc(100% - 105px);
            margin: 0 !important;
        }
    }
</style>
<style lang="scss">
    .trends_btn_wrap{
        .el-checkbox-group{
            label{
                margin: 0 !important;
                margin: 0 10px !important;
                margin-bottom: 15px !important;
            }
        }
    }
    .table_container .el-table .cell{
        text-overflow: initial !important;
    }
</style>

2.父组件-引用此组件主要代码

代码如下(示例):

<trends-table
            ref="trendtable"
            v-loading="tableLoading"
            :table-list="dataList"
            :page-size.sync="authorizeForm.pageSize"
            :page-number.sync="authorizeForm.pageNumber"
            :total="totalRows"
            @getHideColist="getHideColist"
            @pagination="paginationHadle"
          >
            <el-table-column key="name" v-if="!columnHideList['name']" class-name="column_visible" label="姓名" prop="name" align="center" />
            <el-table-column key="age" v-if="!columnHideList['age']" label="年龄" prop="age" align="center" class-name="column_visible"/>
            <el-table-column key="phone" label="手机号" prop="phone" align="center" />
            <el-table-column key="address" label="住址" prop="address" align="center" />
            <el-table-column key="zhiwei" v-if="!columnHideList['zhiwei']" label="职位" prop="zhiwei" align="center" class-name="column_visible" />
            <el-table-column key="operationBtn" label="操作" align="center" width="120" class-name="operation_btn_wrap">
              <template slot-scope="{row,column,$index}">
                <el-button type="text" @click="download(row,$index)">下载</el-button>
                <el-button type="text" @click="lookDetail(row,$index)">详情</el-button>
              </template>
            </el-table-column>
          </trends-table>
// 获得列显示隐藏数据
getHideColist(item) {
    this.columnHideList = item
    this.$forceUpdate()//一定要强制更新视图
},

 


总结

感觉还有实现此类功能更好的方式方法,希望能一步步更好的优化。如有需要直接copy下来就可以直接使用。一些el-table的事件也增加了一部分,如有需要按照el-table的调用方式可以直接使用。