基于element的分页进行的二次封装

在上一篇中,我们针对表格进行了封装,使得我们的开发效率有了一个小小的提升,今天再带大家来对分页进行封装。这样我们表格加分页就组成了一个完整的功能封装。
我们都知道,element官网提供的分页提供了两个重要的属性,page-size(每页显示条目个数)和current-page(当前页数),并且都支持.sync属性。.sync我们熟悉vue的同学都知道,这是官方为我们提供的福利属性,让我们能够实现同时多个双向绑定,这也为我们实现分页等需要同时多个双向绑定的组件带来了很大的帮助,减少了许多开发难度。
同时,我们应该有想到,我们在进行每一次条目和当前页数的改变时,会改变父组件传递过来的数值,这种直接修改是不符合vue单向数据流的思想的,这个时候,我们这里用到官网给与的建议------使用这个 prop 的值来定义一个计算属性的方式来解决。

话不多说,先上图
QQ截图20201110101000.png

如图,我们建立了2个表格,两个表格携带着分页他就向你走来了,而你只需要传两个不同的config就好了
QQ截图20201110101143.png

我们的分页组件很简单,只需要把官网的几个常用属性变成你的prop就好了。
<template>
  <div class="pagination">
    <el-pagination
      background
      :current-page.sync="currentPage"
      :page-size.sync="pageSize"
      :layout="layout"
      :page-sizes="pageSizes"
      :total="total"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
  </div>
</template>
<script>
export default {
  name: 'Pagination',
  props: {
    total: {
      required: true,
      type: Number
    },//数据总数
    page: {
      type: Number,
      default: 1
    },//当前页数
    entry: {
      type: Number,
      default: 5
    },//每页显示条目个数
    pageSizes: {
      type: Array,
      default() {
        return [5,10, 20, 30, 50]
      }
    },//设置一次展示多少行数据
    layout: {
      type: String,
      default: 'total, sizes, prev, pager, next, jumper'
    },//分页的构成,例如是否添加上一页下一页,是否支持输入跳转
  },
  computed: {
    currentPage: {
      get() {
        return this.page
      },
      set(val) {
        this.$emit('update:page', val)
      }
    },//利用计算属性来重置普攻。让我们可以改变父组件传递过来的分页页数和条目
    pageSize: {
      get() {
        return this.entry
      },
      set(val) {
        this.$emit('update:entry', val)
      }
    }
  },
  methods: {
    //改变分页页数和条目,通知父组件做相应的数据改变
    sizeChange(val) {
      this.$emit('pagechange', { page: this.currentPage, entry: val })
    },
    entryChange(val) {
      this.$emit('pagechange', { page: val, entry: this.pageSize })
    }
  }
}
</script>

我们这个分页引入在昨天封装的table组件中

<template>
    <div>
        <el-table
            class="customer"
            :data="tableData"
            style="width: 100%">
            <!-- 循环表头数据,判断列显示类型 -->
            <template v-for="(col,index) in tableHeader">
                <!-- 多选框 -->
                <el-table-column v-if="col.type == 'selection'" :label="col.label" :type="col.type" :width="col.width"></el-table-column>
                <!-- 索引行 -->
                <el-table-column v-else-if="col.type == 'index'" :label="col.label" :type="col.type" :width="col.width"></el-table-column>
                <el-table-column v-else-if="col.type == 'image'" :label="col.label" :width="col.width" :prop="col.prop">
                    <template slot-scope="scope">
                        <div class="content-image"><img :src="scope.row[col.prop]"/></div>
                    </template>
                </el-table-column>
                <el-table-column v-else-if="col.type == 'date'" :label="col.label" :width="col.width" :min-prop="col.prop">
                    <template slot-scope="scope">
                        <i class="el-icon-time"></i>
                        <span style="margin-left: 10px">{{ scope.row[col.prop] }}</span>
                    </template>
                </el-table-column>
                <el-table-column v-else-if="col.type == 'handle'" :label="col.label" :min-width="col.width" :fixed="col.fixed">
                    <template slot-scope="scope">
                        <slot name="handles" :col="scope.row"></slot>
                    </template>
                </el-table-column>
                <el-table-column v-else :label="col.label" :min-width="col.width" :prop="col.prop" :formatter="col.formatter?col.formatter:null">
                </el-table-column>
            </template>
        </el-table>
        <pagination v-show="config.total>0" :total="config.total" v-on="$listeners" :page.sync="config.searchList.page" :entry.sync="config.searchList.pageSize" />
    </div>
</template>
<script>
    import Pagination from '../Pagination/index.vue'
    export default {
        name:'DynamicTable',
        components:{Pagination},
        props:{
            config:{
                type:Object,
                default:()=>{}
            },
            tableHeader:{
                type:Array,
                default:()=>[]
            },
            tableData:{
                type:Array,
                default:()=>[]
            }
        }
    }
</script>

细心的小伙伴儿发现,诶,你这个分页没有通知分页变化改变数据的方法呀??多了个v-on=“listeners”是什么鬼。这个listeners和$attrs是vue提供的 property,一个是prop传递,一个是事件传递。这样我们就可以把在分页组件中定义好的分页方法通知父级组件来进行数据改变

<template>
    <div class="pages-container">
        <dynamic-table :tableHeader="tableHeader" :tableData="tableData" :config="config" @pagechange="getList($event)">
            <template v-slot:handles="t">
                <el-button-group>
                    <el-link type="primary" @click="edit(t)" icon="el-icon-edit">编辑</el-link>
                    <el-link type="danger" @click="deleteId(t)">删除<i class="el-icon-delete el-icon--right"></i> </el-link>
                </el-button-group>
            </template>
        </dynamic-table>
        <dynamic-table style="margin-top: 15px;" :tableHeader="tableHeader2" :tableData="tableData2" :config="config2" @pagechange="getList($event)">
            <template v-slot:handles="t">
                <el-button-group>
                    <el-link type="success" @click="watch(t)" icon="el-icon-view">查看</el-link>
                    <el-link type="warning" @click="publish(t)">发布<i class="el-icon-finished el-icon--right"></i> </el-link>
                </el-button-group>
            </template>
        </dynamic-table>
    </div>
</template>

我们看到,这里我们直接调用了pagetion组件中的分页方法,然后我们拿到分页页数和条目,调用拉取列表的方法就好了。
吕某人这里只是对表格和分页进行了基础封装。有需要loading等更多效果和属性的可以自行进行添加,这里不再赘述,感觉对你有帮助的小伙伴,帮忙点个赞吧,码文不易,谢谢点赞!

©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容