element ui table封装组件,支持自定义列和事件操作

封装element ui table, 支持自定义列的展示和按照指定顺序展示

自定义列需要在引用页面重新写一下,这样就可以定义化了,多数用于一些转换,或者操作列场景下,自行考虑即可,我们粉转成一个组件,那么不用每个table页面按照官方的这种el-table-column写法:

比如这种:

<el-table-column label="状态" >
  <template slot-scope="{row}">
    <span class="link-type">{{ row.status }}</span>
  </template>
</el-table-column>

下面我们封装组件,代码如下 :

1.组件页面:

<template>
  <div class="table-container">
    <el-table
      id="iTable"
      ref="mutipleTable"
      v-loading.iTable="options.loading"
      :data="list"
      :stripe="options.stripe"
      :highlight-current-row="options.highlightCurrentRow"
      border
      height="600"
      @selection-change="handleSelectionChange"
      @row-dblclick="handleRowDblclick"
      @row-click="handleRowClick"
    >
      <!--选择框-->
      <el-table-column v-if="options.mutiSelect" type="selection" style="width: 55px;" />
      <!--end-->
      <!--按钮操作组-->
      <el-table-column
        v-show="typeof operates != 'undefined'"
        v-if="typeof operates != 'undefined' && typeof operates.list !='undefined' && operates.list.filter(_x=>_x.show === true).length > 0"
        ref="fixedColumn"
        label="操作"
        align="center"
        :width="operates.width"
        :fixed="operates.fixed"
      >
        <template slot-scope="scope">
          <div class="operate-group">
            <template v-for="(btn, key) in operates.list">
              <div v-if="btn.show" :key="btn.id" class="item">
                <!--  <span :style="btn.style" size="mini" :class="btn.class" :plain="btn.plain"-->
                <!--  @click="btn.method(key,scope.row)">{{ btn.label }}-->
                <!--  </span>-->
                <el-button
                  :type="btn.type"
                  size="mini"
                  :icon="btn.icon"
                  :disabled="btn.disabled"
                  :plain="btn.plain"
                  @click.native.prevent="btn.method(key,scope.row)"
                >{{ btn.label }}
                </el-button>
              </div>
            </template>
          </div>
        </template>
      </el-table-column>
      <!--end-->
      <!--数据列-->
      <template v-for="(column, index) in columns">
        <el-table-column
          :key="column.label"
          :prop="column.prop"
          :label="column.label"
          :align="column.align"
          :width="column.width"
        >
          <template slot-scope="scope">
            <template v-if="!column.render">
              <template v-if="column.formatter">
                <span v-html="column.formatter(scope.row, column)" />
              </template>
              <template v-else>
                <span>{{ scope.row[column.prop] }}</span>
              </template>
            </template>
            <template v-else>
              <expand-dom :column="column" :row="scope.row" :render="column.render" :index="index" />
            </template>
          </template>
        </el-table-column>
      </template>
      <!--end-->
    </el-table>

    <div class="pagination-container" v-show="showPage">
      <pagination v-show="total>0" :total="total" :page.sync="currentPage" :limit.sync="pageSize" @pagination="handelPageChange" />
    </div>

  </div>
</template>
<!--end-->
<script>
import Pagination from '@/components/Pagination'
export default {
  // 组件
  components: {
    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)
      }
    },
    Pagination
  },
  props: {
    list: {
      type: Array,
      default: function() {
        return []
      }
    }, // 数据列表
    columns: {
      type: Array,
      // Type of the default value for 'options' prop must be a function.(vue/require-valid-default-prop)
      default: function() {
        return []
      }
    }, // 需要展示的列 === prop:列数据对应的属性,label:列名,align:对齐方式,width:列宽
    operates: {
      type: Object,
      default: function() {
        return {}
      }
    }, // 操作按钮组 === label: 文本,type :类型(primary / success / warning / danger / info / text),show:是否显示,icon:按钮图标,plain:是否朴素按钮,disabled:是否禁用,method:回调方法
    options: {
      type: Object,
      default: function() {
        return {
          loading: false, // 不加载loading
          stripe: false, // 是否为斑马纹 table
          highlightCurrentRow: false // 是否要高亮当前行
        }
      }
    }, // table 表格的控制参数
    /**
     * @total 数据总条数
     */
    total: {
      type: Number,
      default: 0
    },
    showPage: {
      type: Boolean,
      default: true
    }
  },
  // 数据
  data() {
    return {
      page: 1,
      limit: 10,
      pageIndex: 1,
      multipleSelection: [] // 多行选中
    }
  },
  computed: {
    currentPage: {
      get() {
        return this.page
      },
      set(val) {
        this.$emit('update:page', val)
      }
    },
    pageSize: {
      get() {
        return this.limit
      },
      set(val) {
        this.$emit('update:limit', val)
      }
    }
  },
  mounted() {
  },
  methods: {

    // 多行选中
    handleSelectionChange(val) {
      this.multipleSelection = val
      this.$emit('handleSelectionChange', val)
    },
    // 显示 表格操作弹窗
    showActionTableDialog() {
      this.$emit('handelAction')
    },
    //翻页
    handelPageChange(val){
      console.log(val)
      this.$emit('handelPageChange', val)
    },
    //单击事件
    handleRowDblclick(val) {
      this.multipleSelection = val
      this.$emit('handleRowDblclick', val)
    },
    //单击行事件
    handleRowClick(val) {
      this.multipleSelection = val
      this.$emit('handleRowClick', val)
    },
  }

}
</script>
<style>
.operate-group {
  display: flex;
  flex-direction: row;
  justify-content: space-around;
}
</style>

2.模板页面调用如下:

<template>
  <div class="app-container calendar-list-container">
    <el-row>
      <el-col :span="24">
        <div>
          <victable
            :list="list"
            @handleSelectionChange="handleSelectionChange"
            @handleRowClick="handleRowClick"
            @handleRowDblclick="handleRowDblclick"
            :options="options"
            :columns="columns"
            :operates="operates"
            @handelPageChange="getList"
            :total="total"
            :page.sync="listQuery.page"
            :limit.sync="listQuery.limit"
            :showPage="isShowPage">
          </victable>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import victable from '@/components/Victable'
import { fetchList } from '@/api/user'

export default {
  name: 'table1',
  components: {
    victable,
  },
  computed: {},
  data() {
    return {
      list: [], // table数据
      listQuery: {
        page: 1,
        limit: 10,
        systemname: undefined,
      },
      total: 0,
      isShowPage: true,
      options: {
        stripe: true,    // 是否为斑马纹 table
        loading: true,    // 是否添加表格loading加载动画
        highlightCurrentRow: true, // 是否支持当前行高亮显示
        mutiSelect: true, // 是否支持列表项选中功能
        total: null,
      }, // table 的参数
          {
            prop: 'fromapp',
            label: '来源',
            align: 'center',
            width: '200px'
          },
          {
            prop: 'name',
            label: '姓名',
            align: 'center',
            width: '200px'
            // formatter: (row, column, cellValue) => {
            //   console.log(row.isenable)
            //   console.log(row)
            //   return `<span style="white-space: nowrap;color: dodgerblue;">${row.metername}</span>`
            // }
          },
          {
            prop: 'username',
            label: '用户名',
            align: 'center',
          },
          {
            prop: 'stations',
            label: '岗位',
            align: 'center',
          },
          {
            prop: 'status',
            label: '状态',
            align: 'center',
            render: (h, params) => {
              return h('span', {
              }, params.row.status === 'open' ? '开启' : '关闭')
            }
          },
          {
            prop: 'role',
            label: '角色',
            align: 'center',
          },
        ],
      // 按钮
      operates: {
        width: 150,
        list: [
          {
            id: '1',
            label: '编辑',
            style: 'cursor:pointer;color: #409eff;',
            show: true,
            class: 'el-icon-edit',
            plain: true,
            type:'primary',
            method: (scope, row) => {
              console.log(scope)
              console.log(row)
              this.handleEdit(row)
            }
          },
          {
            id: '2',
            label: '删除',
            style: 'cursor:pointer;color: #b3450e;',
            class: 'el-icon-delete',
            show: true,
            type:'info',
            disabled: true,
            plain: false,
            method: (index, row) => {
              this.handleDel(row)
            }
          }
        ]
      }
    }
  },
  created() {
    this.getList();
  },
  methods: {
    // 选中行
    handleSelectionChange(val) {
      console.log('val:', val)
    },
    // 编辑
    handleEdit(index, row) {
      console.log(' index:', index)
      console.log(' row:', row)
    },
    // 删除
    handleDel(index, row) {
      console.log(' index:', index)
      console.log(' row:', row)
    },
    handleRowClick(index, row) {
      console.log(index, row)
    },
    handleRowDblclick(index, row){
      console.log(index, row)
    },
    getList(val) {
      // this.listQuery.loading = true
      if(val || val != undefined){
        this.listQuery.page = val.page
        this.listQuery.limit = val.limit
      }
      fetchList(this.listQuery).then(response => {
        this.options.loading = false
        this.list = response.data.items
        this.total = response.data.total
      })
    },
    handleSizeChange(val) {
      console.log(val)
      this.listQuery.limit = val;
      this.getList()
    },
    handleCurrentChange(val) {
      console.log(val)
      this.listQuery.page = val;
      this.getList()
    },
  }
}
</script>

效果如下:

element ui table封装组件,支持自定义列和事件操作

 其中isShowPage可以控制翻页是否显示,当然了组件控制按钮是否显示,按钮的事件,样式,单击行,双击行事件,多选事件,还有其他事件也可以往里面封装,这样就可以节省重复写很多el-table-column这种标签

上一篇:17python实操案例十四


下一篇:使用pymysql读取mysql游标数据集------对结果集进行行列显示,并左右对齐显示