element ui 表格基于vue的二次封装

二次封装原因

1、表格一般使用起来有大部分都是重复的代码,比如el-table-column标签的书写、分页的调用等等。
2、在团队写前端代码时,针对表格每个人都有不同的写法,为了将常见的组件风格保持一致。

二次封装代码

废话不多说,直接上代码。

<template>
  <div class="c-table">
    <!-- 2.表格 -->
    <a-spin :spinning="spinning">
      <div class="opre-box" v-if="btnOperate">
        <div>
          <slot name="slot1"></slot>
        </div>
        <a-popover
          trigger="click"
          v-if="filterCloumn"
          placement="bottomRight"
          overlayClassName="pop-box"
        >
          <template slot="content">
            <a-checkbox-group
              @change="onChange"
              v-model="selectedColumn"
              :defaultValue="selectedColumn"
            >
              <div v-for="item in column">
                <a-tooltip :title="item.name">
                  <a-checkbox :value="item.value">{{ item.name }}</a-checkbox>
                </a-tooltip>
              </div>
            </a-checkbox-group>
          </template>
          <div class="column-pop" @click="showColumm = !showColumm">
            <a-icon type="bars" />
            <a-icon :type="showColumm ? 'up' : 'down'" class="icon" />
          </div>
        </a-popover>
      </div>
      <el-table
        :highlight-current-row="radio"
        :data="tabledata.data"
        @selection-change="handleSelectionChange"
        @current-change="handleCurrentChange"
        @sort-change="sortChange"
        :border="true"
        resizable
        tooltip-effect="dark"
        :height="height"
        ref="cTable"
      >
        <el-table-column type="selection" v-if="selection" width="35" />
        <el-table-column
          label="序号"
          type="index"
          v-if="index.show"
          :fixed="index.fixed"
          width="50"
        />
        <template v-for="(item, index) in column">
          <el-table-column
            :key="index"
            :prop="item.value"
            :width="typeof item.width === 'undefined' ? '' : item.width"
            :label="item.name"
            :sortable="item.sortable ? 'custom' : false"
            v-if="selectedColumn.indexOf(item.value) > -1"
            show-overflow-tooltip
          >
            <template slot-scope="scope">
              <expand
                v-if="item.render"
                :render="item.render"
                :row="scope.row"
                :index="index"
                :column="item"
              ></expand>
              <span v-else>{{ scope.row[item.value] }}</span>
            </template>
          </el-table-column>
        </template>
        <!-- <slot v-if="operate" name="slot"></slot> -->
        <el-table-column
          v-if="operate.show"
          :label="operate.title ? operate.title : '操作'"
          :width="typeof operate.width === 'undefined' ? 120 : operate.width"
          :fixed="operate.fixed"
        >
          <template slot-scope="scope">
            <slot :row="scope.row" name="slot2"></slot>
          </template>
        </el-table-column>
      </el-table>
    </a-spin>
    <!-- 3.表格分页 -->
    <el-pagination
      v-if="tabledata.meta.total > 0"
      :current-page="tabledata.meta.currentPage"
      :total="tabledata.meta.total"
      :page-size="tabledata.meta.pageSize"
      :page-sizes="[10, 20, 40, 60, 80, 100]"
      @size-change="handelSizeChange"
      @current-change="handelCurrentChange"
      layout="total,sizes,prev,pager,next,jumper"
    ></el-pagination>
    <div class="table-operation-title" v-if="tabledata.meta.total > 0">
      <span class="show">每页展示</span>
      <span>
        <a-button type="primary" class="show-btn">确定</a-button>
      </span>
    </div>
  </div>
</template>

<script>
import expand from "./expand";
export default {
  //tabledata:表格数据,column:父组件中传过来的需要进行筛选的表格列,用于筛选气泡框的数据渲染
  props: {
    tabledata: {
      type: Object,
      required: true
    },
    column: {
      type: Array,
      required: true
    },
    selection: {
      type: Boolean,
      default: true
    },
    //高亮单选
    radio: {
      type: Boolean,
      default: false
    },
    spinning: {
      type: Boolean,
      default: false
    },
    height: {
      default: null
    },
    //序号
    index: {
      type: Object,
      default: () => {
        return {
          fixed: false,
          show: false,
          title: "操作"
        };
      }
    },
    //操作
    operate: {
      type: Object,
      default: () => {
        return {
          fixed: false,
          show: false,
          wdith: 120
        };
      }
    },
    //是否显示表格上方一行操作项
    btnOperate: {
      type: Boolean,
      default: true
    },
    //是否显示表格右上方字段显示按钮
    filterCloumn: {
      type: Boolean,
      default: true
    }
  },
  components: { expand },
  data() {
    return {
      // 一:表格相关的数据
      multipleSelection: [], //表格选择框选择的数据
      showColumm: false,
      selectedColumn: [] //表格中被选中列
    };
  },

  methods: {
    //一.表格选择框选中所触发的事件
    handleSelectionChange(val) {
      this.multipleSelection = val;
      this.$emit("coloumSelect", val);
    },

    //表格单选触发
    handleCurrentChange(val) {
      if (this.radio) {
        this.$emit("coloumCurrent", val);
      }
    },
    //二.分页相关的方法
    handelSizeChange(val) {
      this.tabledata.meta.pageSize = val;
      this.handelCurrentChange();
    },
    handelCurrentChange(val) {
      this.tabledata.meta.currentPage = typeof val == "undefined" ? 1 : val;
      this.$emit("queryData");
    },

    // 2.筛选表格列的选择框默认全选中
    init() {
      this.column.forEach(item => {
        this.selectedColumn.push(item.value);
      });
    },
    /**
     * @Author: liu.yihu
     * @des: 远程排序
     * @param {type}
     * @return:
     */
    sortChange(column) {
      this.tabledata.meta.field = column.prop;
      this.tabledata.meta.sort = column.order == "ascending" ? "asc" : "desc";
      this.$emit("queryData");
    },
    //3.表格列的筛选
    onChange(checkedValues) {
      this.selectedColumn = checkedValues;
    }
  },
  created() {},
  mounted() {
    this.init();
  }
};
</script>

expand.js

export default {
  name: 'expand',
  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)
  },
}

使用方式

template代码

 <c-table
      :tabledata="tableData"
      :column="column"
      @queryData="queryData"
      :operate="{show:true}"
      :spinning="spinning"
      :selection="true"
    >
      <template slot-scope="scope" slot="slot2">
        <div class="operation-btn">
          <a-tooltip>
            <template slot="title">接收报文</template>
            <a-icon type="select" class="select-icon" @click="clickAccept(scope.row)" />
          </a-tooltip>
          <a-tooltip>
            <template slot="title">返回报文 </template>
            <a-icon type="rollback" class="rollback-icon" @click="clickBack(scope.row)" />
          </a-tooltip>
        </div>
      </template>
    </c-table>

列render渲染

  column: [
        {
          value: "ewsId",
          name: "工单编号",
          sortable: true,
          render: (h, params) => {
            return h(
              "router-link",
              {
                props: {
                  to: {
                    name: "AOorderDetail",
                    params: {
                      order: params.row
                    }
                  }
                },
              },
              params.row.ewsId
            );
          }
        },
        { value: "oldOrderId", name: "原工单号", sortable: true },
        { value: "productName", name: "产品名称", sortable: true },
        { value: "createTime", name: "创建时间", sortable: true },
        { value: "updateTime", name: "更新时间", sortable: true }
      ],

注意:表格查询方法未封装在表格组件中,需在各个vue文件中重新声明,感兴趣的同学可以将查询方法也封装在表格组件中。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值