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

1,437 阅读2分钟

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

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

image.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”是什么鬼。这个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等更多效果和属性的可以自行进行添加,这里不再赘述,感觉对你有帮助的小伙伴,帮忙点个赞吧,码文不易,谢谢点赞!