美文网首页💚💚VUE 💚💚
结合Element-Ui的分页

结合Element-Ui的分页

作者: Shiyouzhang | 来源:发表于2019-08-24 19:20 被阅读0次

    1、背景

    最近突然想起来好久没有写和页有关的东西,正好昨晚和别人讨论到了,所以就想结合Element来写一点了。

    2、实现思路

    2.1、Element UI 引入(整体引入)

    main.js
    
    // Element UI
    import Element from 'element-ui'
    // 默认样式
    import 'element-ui/lib/theme-chalk/index.css'
    复制代码
    

    2.2、开始封装 iTable.vue 组件 (骨架)

    由于公司项目都是以 i 开头,所以,为了区分组件和页面,习惯于组件命名也以 i 开头。 首先把 TablePagination 组件加进来

    <template>
      <div class="table">
    
         <!--region 表格-->
         <el-table id="iTable"></el-table>
         <!--endregion-->
    
         <!--region 分页-->
         <el-pagination></el-pagination>
         <!--endregion-->
    
      </div>
    <template>
    
    

    养成写注释的好习惯,个人项目的注释量基本上不会低于 30%

    2.3、在页面中引用 iTable 组件,并且给 iTable 组件传值

    <template>
      <div class="table-page">
        <!--region table 表格-->
        <i-table
        :list="list"
        :total="total" 
        :otherHeight="otherHeight" 
        :options="options"
        :pagination="pagination"
        :columns="columns" 
        :operates="operates" 
        @handleSizeChange="handleSizeChange"
        @handleIndexChange="handleIndexChange" 
        @handleSelectionChange="handleSelectionChange" 
        @handleFilter="handleFilter" 
        @handelAction="handelAction">
        </i-table>
        <!--endregion-->
      </div>
    </template>
    <script>
      import iTable from '../../components/Table/Index'
    
      export default {
        components: {iTable},
        data () {
          return {
            total: 0,
            list: [],
            otherHeight: 208,
            columns: [
              {
                prop: 'id',
                label: '编号',
                align: 'center',
                width: 60
              },
              {
                prop: 'title',
                label: '标题',
                align: 'center',
                width: 400,
                formatter: (row, column, cellValue) => {
                  return `<span style="white-space: nowrap;color: dodgerblue;">${row.title}</span>`
                }
              },
              {
                prop: 'state',
                label: '状态',
                align: 'center',
                width: '160',
                render: (h, params) => {
                  return h('el-tag', {
                    props: {type: params.row.state === 0 ? 'success' : params.row.state === 1 ? 'info' : 'danger'} // 组件的props
                  }, params.row.state === 0 ? '上架' : params.row.state === 1 ? '下架' : '审核中')
                }
              },
              {
                prop: 'author',
                label: '作者',
                align: 'center',
                width: 120
              },
              {
                prop: 'phone',
                label: '联系方式',
                align: 'center',
                width: 160
              },
              {
                prop: 'email',
                label: '邮箱',
                align: 'center',
                width: 240
              },
              {
                prop: 'createDate',
                label: '发布时间',
                align: 'center',
                width: 180,
                formatter: (row, column, cellValue) => {
                  return this.$utils.Common.dateFormat(row.createDate, 'YYYY年MM月DD日 hh:mm')
                }
              }
            ], // 需要展示的列
            operates: {
              width: 200,
              fixed: 'right',
              list: [
                {
                  label: '编辑',
                  type: 'warning',
                  show: : (index, row) => {
                    retuen true
                  },
                  icon: 'el-icon-edit',
                  plain: true,
                  disabled: false,
                  method: (index, row) => {
                    this.handleEdit(index, row)
                  }
                },
                {
                  label: '删除',
                  type: 'danger',
                  icon: 'el-icon-delete',
                  show: true,
                  plain: false,
                  disabled: (index, row) => {
                    retuen false
                  },
                  method: (index, row) => {
                    this.handleDel(index, row)
                  }
                }
              ]
            }, // 操作按钮组
            pagination: {
              pageIndex: 1,
              pageSize: 20
            }, // 分页参数
            options: {
              stripe: true, // 是否为斑马纹 table
              loading: false, // 是否添加表格loading加载动画
              highlightCurrentRow: true, // 是否支持当前行高亮显示
              mutiSelect: true // 是否支持列表项选中功能
            } // table 的参数
          }
        },
        components: {
          expandDom: {
            props: {
              column: {
               required: true
              },
              row: {
                required: true
              }
            },
            render (h) {
              return h('div', {}, ([this.column.render(this.row, this.column)]))
            }
         }
       },
        mounted () {
        },
        methods: {
          // 切换每页显示的数量
          handleSizeChange (pagination) {
            this.pagination = pagination
          },
          // 切换页码
          handleIndexChange (pagination) {
            this.pagination = pagination
          },
          // 选中行
          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)
          }
        }
      }
    </script>
    
    

    除了 columns 参数和 operates 参数 之外,其它的参数应该还好理解,好的。那我们就详细的解释下这两个参数,那么我们就需要结合组件iTable.vue 来讲解了,接下来就给 iTable.vue 添加肌肉和血管,代码都贴了。 比较难理解的就是columns里面的 render 参数,使用了Vue的虚拟标签,为了就是能够在 table 表格的列中随心所欲的使用各种html标签 和 element UI 的其他组件。(你也可以直接写,看看 table 组件是否能识别,呵呵哒!)这个估计对于刚入门的小伙伴是一个比较难理解的地方,详细的大家可以先看下vue 的 render,解释的更清楚,如果有的小伙伴不理解,可以直接私信我~~~

    <!--region 封装的分页 table-->
    <!--region 封装的分页 table-->
    <template>
      <div class="table">
        <el-table 
        id="iTable" 
        v-loading.iTable="options.loading" 
        :data="list" 
        :max-height="height" 
        :stripe="options.stripe"
        ref="mutipleTable"
        @selection-change="handleSelectionChange">
          <!--region 选择框-->
          <el-table-column v-if="options.mutiSelect" type="selection" style="width: 55px;">
          </el-table-column>
          <!--endregion-->
          <!--region 数据列-->
          <template v-for="(column, index) in columns">
            <el-table-column :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)"></span>
                  </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"></expand-dom>
                </template>
              </template>
            </el-table-column>
          </template>
          <!--endregion-->
          <!--region 按钮操作组-->
          <el-table-column ref="fixedColumn" label="操作" align="center" :width="operates.width" :fixed="operates.fixed"
                           v-if="operates.list.length > 0">
            <template slot-scope="scope">
              <div class="operate-group">
                <template v-for="(btn, key) in operates.list">
                  <div class="item" v-if="!btn.show||&&btn.show(scope.$index,scope.row)">
                    <el-button :type="btn.type" size="mini" :icon="btn.icon" :disabled="btn.disabled||&&btn.disabled(scope.$index,scope.row)"
                               :plain="btn.plain" @click.native.prevent="btn.method(key,scope.row)">{{ btn.label }}
                    </el-button>
                  </div>
                </template>
              </div>
            </template>
          </el-table-column>
          <!--endregion-->
        </el-table>
        <div style="height:12px"></div>
        <!--region 分页-->
        <el-pagination v-if="pagination" @size-change="handleSizeChange"
                       @current-change="handleIndexChange"
                       :page-size="tableCurrentPagination.pageSize"
                       :page-sizes="this.tableCurrentPagination.pageArray" :current-page="tableCurrentPagination.pageIndex"
                       layout="total,sizes, prev, pager, next,jumper"
                       :total="total"></el-pagination>
        <!--endregion-->
      </div>
    </template>
    <!--endregion-->
    <script>
      const _pageArray = [20, 50, 100] // 每页展示条数的控制集合
      export default {
        props: {
          list: {
            type: Array,
            default: [] // prop:表头绑定的地段,label:表头名称,align:每列数据展示形式(left, center, right),width:列宽
          }, // 数据列表
          columns: {
            type: Array,
            default: [] // 需要展示的列 === prop:列数据对应的属性,label:列名,align:对齐方式,width:列宽
          },
          operates: {
            type: Object,
            default: {} // width:按钮列宽,fixed:是否固定(left,right),按钮集合 === label: 文本,type :类型(primary / success / warning / danger / info / text),show:是否显示,icon:按钮图标,plain:是否朴素按钮,disabled:是否禁用,method:回调方法
          },
          total: {
            type: Number,
            default: 0
          }, // 总数
          pagination: {
            type: Object,
            default: null // 分页参数 === pageSize:每页展示的条数,pageIndex:当前页,pageArray: 每页展示条数的控制集合,默认 _page_array
          },
          otherHeight: {
            type: Number,
            default: 160
          }, // 计算表格的高度
          options: {
            type: Object,
            default: {
              stripe: false, // 是否为斑马纹 table
              loading: false, // 是否添加表格loading加载动画
              highlightCurrentRow: false, // 是否支持当前行高亮显示
              mutiSelect: false // 是否支持列表项选中功能
            }
          } // table 表格的控制参数
        },
        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)
            }
          }
        },
        data () {
          return {
            pageIndex: 1,
            tableCurrentPagination: {},
            multipleSelection: [] // 多行选中
          }
        },
        created () {},
        mounted () {
          if (this.pagination && !this.pagination.pageSizes) {
            this.pagination.pageArray = _pageArray // 每页展示条数控制
          }
          this.tableCurrentPagination = this.pagination || {
            pageSize: this.total,
            pageIndex: 1
          } // 判断是否需要分页
        },
        computed: {
          // 计算table高度
          height () {
            return this.$utils.Common.getWidthHeight().height - this.otherHeight
          }
        },
        methods: {
          // 切换每页显示的数量
          handleSizeChange (size) {
            if (this.pagination) {
              this.tableCurrentPagination = {
                pageIndex: 1,
                pageSize: size
              }
              this.$emit('handleSizeChange', this.tableCurrentPagination)
            }
          },
          // 切换页码
          handleIndexChange (currnet) {
            if (this.pagination) {
              this.tableCurrentPagination.pageIndex = currnet
              this.$emit('handleIndexChange', this.tableCurrentPagination)
            }
          },
          // 多行选中
          handleSelectionChange (val) {
            this.multipleSelection = val
            this.$emit('handleSelectionChange', val)
          },
          // 显示 筛选弹窗
          showfilterDataDialog () {
            this.$emit('handleFilter')
          },
          // 显示 表格操作弹窗
          showActionTableDialog () {
            this.$emit('handelAction')
          }
        }
      }
    </script>
    
    <style lang="less" rel="stylesheet/less">
      @import "../../assets/styles/mixins";
    
      .table {
        height: 100%;
        .el-pagination {
          float: right;
          margin: 20px;
        }
        .el-table__header-wrapper, .el-table__fixed-header-wrapper {
          thead {
            tr {
              th {
                color: #333333;
              }
            }
          }
        }
        .el-table-column--selection .cell {
          padding: 0;
          text-align: center;
        }
        .el-table__fixed-right {
          bottom: 0 !important;
          right: 6px !important;
          z-index: 1004;
        }
        .operate-group {
          display: flex;
          flex-wrap: wrap;
          .item {
            margin-top: 4px;
            margin-bottom: 4px;
            display: block;
            flex: 0 0 50%;
          }
        }
        .filter-data {
          top: e("calc((100% - 100px) / 3)");
          background-color: rgba(0, 0, 0, 0.7);
        }
        .table-action {
          top: e("calc((100% - 100px) / 2)");
          background-color: rgba(0, 0, 0, 0.7);
        }
        .fix-right {
          position: absolute;
          right: 0;
          height: 100px;
          color: #ffffff;
          width: 30px;
          display: block;
          z-index: 1005;
          writing-mode: vertical-rl;
          text-align: center;
          line-height: 28px;
          border-bottom-left-radius: 6px;
          border-top-left-radius: 6px;
          cursor: pointer;
        }
      }
    </style>
    
    

    不知道什么原因图片上传不了,所以就没有加上效果图。
    这些其实就是在Element粘贴复制就好 但不知很多人为什么就是不会。

    相关文章

      网友评论

        本文标题:结合Element-Ui的分页

        本文链接:https://www.haomeiwen.com/subject/gqgqectx.html