vue2.5.10+element-ui2.6.1公共组件table与分页器封装

159 阅读1分钟

1.自定义Tables.vue组件

<template>
  <div class="tables-content">
    <!-- table start -->
    <el-table v-loading="loading" v-bind="tableConfig">
      <template v-for="(item, index) in columns">
        <!-- 自定义列 -->
        <el-table-column v-if="item.slotName" :key="index" v-bind="item">
          <template slot-scope="scope">
            <slot :name="item.slotName" :scope="scope"></slot>
          </template>
        </el-table-column>
        <!-- 原始列 -->
        <el-table-column v-else :key="index" v-bind="item"></el-table-column>
      </template>
    </el-table>
    <!-- table end -->

    <!-- 分页器 start -->
    <template v-if="pagerConfig.show">
      <el-pagination
        v-bind="pagerConfig"
        @size-change="sizeChange"
        @current-change="currentChange"
        @prev-click="prevClick"
        @next-click="nextClick"
      ></el-pagination>
    </template>
    <!-- 分页器 end -->
  </div>
</template>

<script>
export default {
  name: "Tables",
  props: {
    loading: {
      type: Boolean,
      default: false
    },
    columns: {
      // 栏目 shlotName
      type: Array,
      default() {
        return [];
      }
    },
    tableConfig: {
      // tableConfig的配置属性,与element-ui组件下table的属性一样
      type: Object,
      default() {
        return {};
      }
    },
    // tableEvent: { // 事件需要手动通过@的形式一个一个添加,v-on="{}"的形式不生效
    //   // tanle事件
    //   type: Object,
    //   default() {
    //     return {
    //       rowClick: () => {console.log('/???')}
    //     };
    //   }
    // },
    pagerConfig: {
      // 分页器属性
      type: Object,
      default() {
        return {};
      }
    },
    pagerEvent: {
      // 分页器事件
      type: Object,
      default() {
        return {};
      }
    }
  },
  data() {
    return {};
  },
  methods: {
    // 由于v-on="{}"的形式不生效,所以以这种方式对分页器的事件调用进行传递
    sizeChange(s) {
      // pageSize 改变时会触发
      this.pagerEvent.sizeChange && this.pagerEvent.sizeChange(s);
    },
    currentChange(i) {
      // currentPage 改变时会触发
      this.pagerEvent.currentChange && this.pagerEvent.currentChange(i);
    },
    prevClick(i) {
      // 用户点击上一页按钮改变当前页后触发
      console.log(i);
      this.pagerEvent.prevClick && this.pagerEvent.prevClick(i);
    },
    nextClick(i) {
      // 用户点击下一页按钮改变当前页后触发
      this.pagerEvent.nextClick && this.pagerEvent.nextClick(i);
    }
  }
};
</script>

<style rel="stylesheet/scss" lang="scss" scoped></style>

2.页面

<template>
    <div>
        <Tables
            :loading="loading"
            :columns="columns"
            :tableConfig="tableConfig"
            :pagerEvent="pagerEvent"
         >
          // 自定义列内容
          <template slot="set" slot-scope="{ scope }">
            <el-button size="mini" @click="handleEdit(scope.$index, scope.row)"
              >编辑</el-button
            >
            <el-button
              size="mini"
              type="danger"
              @click="handleDelete(scope.$index, scope.row)"
              >删除</el-button
            >
          </template>
        </Tables>
    </div>
</template>

<script>
import Tables from "@/components/Tables";
export default {
  data() {
      return {
          loading: false,
          // 配置table的header,与element官网的Table-column Attributes下的属性一样,注意驼峰
          columns: [{
                label: 'Id',
                prop: 'id',
                align: 'center'
              }, {
                label: '姓名',
                prop: 'name',
                align: 'center'
              }],
              // 配置table下的属性,与elemen官网的Table Attributes下的属性一样,注意驼峰
              tableConfig: {
                border: true,
                data: [{ // 数据
                  id: '1',
                  name: '张三'
                }, {
                  id: '2',
                  name: '李四'
                },
                {
                  label: "操作",
                  // 自定义table列的内容时不需要prop,需要slotName与template上的slot的值保持一致,slot也可以直接定义在不同标签或组件上,slot-scope="{ scope }"返回数据信息用于操作使用
                  slotName: 'set', 
                  align: "center"
                }]
              },
              // 分页器的属性配置
               pagerConfig: {
                show: true,
                currentPage: 2,
                pageiSzes: [100, 200, 300, 400],
                pageSize: 100,
                layout: "sizes, prev, pager, next",
                total: 1000
              },
              // 分页的事件配置
              pagerEvent: {
                  sizeChange:(s) => {
                      console.log(s)
                  },
                  currentChange:(i) => {
                      console.log(i)
                  },
                  prevClick:(i) => {
                      console.log(i)
                  },
                  nextClick:(i) => {
                      console.log(i)
                  }
              },
              methods: {
                  // 操作按钮的方法
                  methods: {
                    handleEdit(i, row){ // 编辑方法
                      console.log(i,row);
                    },
                    handleDelete(i, row){ // 删除方法
                      console.log(i,row);
                    },
                  }
              },
              components: {
                Tables
              },
      }
  }
</script>

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

3.效果如图所示

企业微信截图_16230332261038.png

4.遗留问题

  1. 事件的绑定不支持v-on="{}"的形式绑定,不知道有无更好的绑定方法
  2. 封装的table用于基本的table展示似乎没有问题,较为复杂的还没有实践有什么问题暂且未知
  3. table上的事件太多了,没有进行单独的绑定,需要的话可以自行绑定,绑定方式类似与分页器事件的绑定形式。(如果有那位大神有什么好的方式,也希望可以教教我)