vue封装el-table实现高度配置化

1、封装 Table.vue:

<template>
  <div id="ETable">
    <el-table
      ref="Table"
      :data="data"
      v-bind="$attrs"
      v-on="$listeners"
    >
      <el-table-column
        v-if="selectable"
        type="selection"
        v-bind="getSelectionBind()"
      >
      </el-table-column>

      <el-table-column
        v-if="!noIndex"
        type="index"
        v-bind="getIndexBind()"
      ></el-table-column>

      <el-table-column
        v-for="(item,index) in items"
        :key="index"
        v-bind="getBind(item)"
      >

        <template
          v-if="$scopedSlots[item.prop]"
          #default="scope"
        >
          <slot
            :name='item.prop'
            :item='item'
            v-bind="scope"
          />
        </template>

        <template
          v-else-if="item.type"
          #default="{row}"
        >

          <component :is="item.type" v-bind="item.bind(row[item.prop])"/> 
          
        </template>


      </el-table-column>

      <el-table-column
        v-if="$scopedSlots.default"
        v-bind="getOperaBind()"
        #default="scope"
      >

        <slot v-bind="scope" />

      </el-table-column>

      <el-empty
        v-if="!disEmpty"
        slot="empty"
        description="暂无数据"
      ></el-empty>

    </el-table>

    <el-pagination
      v-if="page"
      v-bind="page"
      @size-change="_c_size_change"
      @current-change="_c_page_change"
    />

  </div>

</template>
<script>
import * as _ from "lodash";


let config = {
  defIndexBind: { label: "序号", width: "80px", align: "center" },
  defOperaBind: { label: "操作", width: "200px", align: "center" },
  selectionBind: { width: "50px" },
  defBind: { align: "center", } 
}
export default {
  config,

  props: {
    data: Array,
    items: Array,
    page: Object,

    noIndex: Boolean,
    selectable: Boolean,

    operaBind: Object,
    indexBind: Object,

    selectionBind: Object,
    disEmpty: Boolean
  },
  mounted() {
    this.$nextTick(function () {
      this.setColSpan();
    });
  },
  methods: {
    // 暂时只支持单层的表头合并,多层的后面再说
    setColSpan() {
      let cells = this.$el.getElementsByClassName("el-table__header")[0].rows[0].cells;

      if (!cells) return;

      this.items?.forEach((item, index) => {
        let i = this.noIndex ? index : index + 1;

        if (item.colSpan === 0) {
          cells[i].style.display = "none";
        } else {
          cells[i].colSpan = item.colSpan || 1;
        }
      });
    },
    //----------普通方法-----------
    clearSelection() {
      this.$refs.Table.clearSelection();
    },
    toggleRowSelection() {
      this.$refs.Table.toggleRowSelection.apply(this, [...arguments]);
    },
    toggleRowsSelection(rows, flag) {
      this.$refs.Table.clearSelection();
      rows?.forEach((row) => {
        this.$refs.Table.toggleRowSelection(row, flag);
      });
      
    },
    getOperaBind() {
      let bind = this.operaBind || {};
      let def = _.cloneDeep(config.defOperaBind)

      return _.merge(def, bind);
    },
    getIndexBind() {
      let bind = this.indexBind || {};
      let def = _.cloneDeep(config.defIndexBind)

      return _.merge(def, bind);
    },
    getSelectionBind() {
      let bind = this.selectionBind || {};
      let def = _.cloneDeep(config.selectionBind)

      return _.merge(def, bind);
    },
    getBind(item) {
      let def = _.cloneDeep(config.defBind)

      return _.merge(def, item);
    },

    //----------点击事件-----------
    _c_size_change(val) {
      this.page.pageSize = val;
      this.$emit("page-change", this.page.pageNo);
    },
    _c_page_change(val) {
      this.$emit("page-change", val);
    },

    //----------接口方法-----------
  },
};
</script>
<style lang="scss">
.mycell, .mycell .cell{
  padding: 0!important
}
</style>

2、用法:

<template>
  <div>

    <ETable 
      :data="tableData" 
      :items="items"
      height="70vh"
      border
      :page.sync="page"
      @page-change="_c_page_change">

      <template #name="{row, item}">
        自定义:<el-tag>{{row[item.prop]}}</el-tag>
      </template>

      <template #default="{row, item}">
        <EBtn mode="detail" @click="_c_add"/>
        <EBtn mode="update" @click="_c_update(row)"/>
        <EBtn mode="delete" @click="_c_delete"/>
      </template>
    </ETable>
  </div>
</template>

<script>
import crud_mixin from '@/mixins/crud_mixin.js'
export default {
  mixins: [crud_mixin],
  data() {
    let _this = this
    return {
      tableData: [
        {
          id: 10201,
          created_at: "2022-05-23T09:52:44.655+08:00",
          updated_at: "2022-05-23T10:01:25.571+08:00",
          is_deleted: 0,
          name: "张三",
          age: 21,
          sex: 1,
          org_id: 57,
          detail: [
            { name: '情况1' },
            { name: '情况2' },
          ],
          address: "111",
          manager_name: "王sir",
          manager_id: 25,
          tel: "13451820534",
        },
        {
          id: 10177,
          created_at: "2022-04-06T11:21:10.794+08:00",
          updated_at: "2022-04-06T11:30:50.51+08:00",
          is_deleted: 0,
          name: "姓名",
          age: 21,
          sex: 0,
          org_id: 52,
          detail: [
            { name: '情况1' },
            { name: '情况2' },
          ],
          address: "22",
          manager_name: "小委",
          manager_id: 30,
          tel: "13451820538",
        },
        {
          id: 10175,
          created_at: "2022-04-01T16:04:42.217+08:00",
          updated_at: "2022-04-01T16:07:49.398+08:00",
          is_deleted: 0,
          name: "奥特曼11",
          age: 9991,
          sex: 1,
          org_id: 2,
          detail: [
            { name: '情况1' },
            { name: '情况2' },
          ],
          address: "M781",
          manager_name: "哥斯拉1",
          manager_id: 200,
          tel: "1234561",
        },
        {
          id: 10171,
          created_at: "2022-03-14T10:34:12+08:00",
          updated_at: "2022-03-14T10:34:12+08:00",
          is_deleted: 0,
          name: "姚春华",
          age: 1981,
          sex: 1,
          detail: [
            { name: '情况1' },
            { name: '情况2' },
          ],
          address: "沙家圩村星月花园49-1506",
          tel: "18862953186",
        },
        {
          id: 10170,
          created_at: "2022-03-14T10:34:12+08:00",
          updated_at: "2022-03-14T10:34:12+08:00",
          is_deleted: 0,
          name: "顾金水",
          age: 1969,
          sex: 1,
          detail: [
            { name: '情况1' },
            { name: '情况2' },
          ],
          address: "源兴社区居委会源兴花苑8-103",
          tel: "18862931462",
        },
        {
          id: 10169,
          created_at: "2022-03-14T10:34:12+08:00",
          updated_at: "2022-03-14T10:34:12+08:00",
          is_deleted: 0,
          name: "姜美香",
          age: 1967,
          sex: 0,
          detail: [
            { name: '情况1' },
            { name: '情况2' },
          ],
          address: "源兴社区居委会源兴花苑9-204",
          tel: "18862931462",
        },
        {
          id: 10168,
          created_at: "2022-03-14T10:34:12+08:00",
          updated_at: "2022-03-14T10:34:12+08:00",
          is_deleted: 0,
          name: "施兴华",
          age: 1958,
          sex: 1,
          detail: [
            { name: '情况1' },
            { name: '情况2' },
          ],
          address: "源兴社区居委会源兴花苑41-402",
          tel: "18862931462",
        },
        {
          id: 10167,
          created_at: "2022-03-14T10:34:12+08:00",
          updated_at: "2022-03-14T10:34:12+08:00",
          is_deleted: 0,
          name: "黄聪明",
          age: 1957,
          sex: 1,
          detail: [
            { name: '情况1' },
            { name: '情况2' },
          ],
          address: "朝阳社区四圩桥村8组",
          tel: "15996582978",
        },
        {
          id: 10166,
          created_at: "2022-03-14T10:34:12+08:00",
          updated_at: "2022-03-14T10:34:12+08:00",
          is_deleted: 0,
          name: "胡顺英",
          age: 1965,
          sex: 0,
          detail: [
            { name: '情况1' },
            { name: '情况2' },
          ],
          address: "朝阳社区四圩桥村一组",
          tel: "15996582978",
        },
        {
          id: 10165,
          created_at: "2022-03-14T10:34:12+08:00",
          updated_at: "2022-03-14T10:34:12+08:00",
          is_deleted: 0,
          name: "陈圣珍",
          age: 1943,
          sex: 0,
          detail: [
            { name: '情况1' },
            { name: '情况2' },
          ],
          address: "朝阳社区朝阳花苑21-302",
          tel: "15996582978",
        },
      ],
      items: [
        { prop: "name", label: "弱势群体人员姓名", colSpan: 0 },
        { 
          prop: "age", 
          label: "出生年份",
          type: 'ETag',    // 这是自己封装的组件名称
          bind:val => ({
            text: val+'',
            effect: 'plain',
          }) 
        },
        {
          prop: "sex",
          label: "性别",
          type: 'el-image',
          bind:value => {
            let src = {
              1: require(`@/assets/images/boy.png`),
              0: require(`@/assets/images/girl.png`),
            }[value] || require(`@/assets/images/unknown.png`)
            return {
              src,
              'preview-src-list': [src],
              style:{
                width: '40px',
              }
            }
          }
        },
        { 
          prop: "address", 
          label: "住址",
          formatter(row, col, value){
            return value + '111'
          } 
        },
        { 
          prop: "detail", 
          label: "具体情况",
          'class-name': 'mycell',
          type: 'ECellList',    // 这是自己封装的组件名称
          bind: value => ({
            data: value,
            getItemText: (item, index) => (index+1) +'、'+ item.name
          })
        },
        { prop: "manager_name", label: "帮扶责任人" },
        { prop: "tel", label: "帮扶责任人联系电话" },
      ],
    };
  },
  mounted() {},
  methods: {
  },
};
</script>

<style></style>

3、效果:

4、一般表格会用到crud_mixin.js:

import * as _ from 'lodash'
export default {
  data() {
    return {
      page: {
        pageNo: 1,
        pageSize: 10,
        total: 0,
        pageSizes: [10, 20, 30, 40],
        layout: "total, sizes, prev, pager, next, jumper",
        pagerCount: 5,
        background: true,
      },
      isEditDialogVisible: false,
      isAdd: true,
      loading:false,
      curRow: null,
    }
  },
  watch:{
    'page.pageNo'(n, o){
      this.page['current-page'] = n
    }
  },
  created(){
  },
  mounted(){

  },
  methods: {
    _m_tip(msg){
      this.$message.success(msg);
      this.isEditDialogVisible = false;
      this._c_query();
    },
    _c_query() {
      this.$set(this.page, 'pageNo', 1)
      this._i_query();
    },
    _c_add(row){
      this.$set(this, 'editForm', this.$options.data().editForm)
      this.isAdd=true;
      this.isEditDialogVisible=true
      
      this.curRow = row
    },
    _c_update(row) {
      this.editForm = _.cloneDeep(row);
      this.isAdd = false;
      this.isEditDialogVisible = true;
      
      this.curRow = row
    },
    _c_delete(row, $index) {
      this.curRow = row
      this.$confirm('确认删除吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(res => {
          this._i_delete(row, $index);
        },res => {}
      );
    },
    _c_confirm(isAdd){
      isAdd? this._i_add():this._i_update()
    },
    _c_page_change(val) {
      this.page.pageNo = val;
      this._i_query();
    },
  }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值