您的当前位置:首页正文

Vue2.5 结合 Element UI 之 Table 和 Pagination 组件实现分页功能

2020-11-27 来源:爱够旅游网

2017年底了,总结了这一年多来的前端之路,Vue从入门到放弃,再二进宫,从 Vue1.0 持续跟踪到 Vue2.5。结合公司的一些实际项目,也封装了一些比较实用的组件。

由于现在公司管理平台主要运用Element UI,索性就结合组件Table 和 Pagination 封装了一个支持页面切换的Table组件,不啰嗦,直接上代码。

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 开头。 首先把 Table 、 Pagination 组件加进来

<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">
 <i-table :list="list" 
 :total="total" 
 :otherHeight="otherHeight"
 @handleSizeChange="handleSizeChange"
 @handleIndexChange="handleIndexChange" @handleSelectionChange="handleSelectionChange"
 :options="options"
 :columns="columns"
 :operates="operates"
 @handleFilter="handleFilter"
 @handelAction="handelAction">
 </i-table>
 </div>
</template>
<script>
 import iTable from '../../components/Table/Index'
 export default {
 components: {iTable},
 data () {
 return {
 total: 0, // table数据总条数
 list: [], // table数据
 otherHeight: 208, // 除了table表格之外的高度,为了做table表格的高度自适应
 page: 1, // 当前页码
 limit: 20, // 每页数量
 options: {
 stripe: true, // 是否为斑马纹 table
 loading: false, // 是否添加表格loading加载动画
 highlightCurrentRow: true, // 是否支持当前行高亮显示
 mutiSelect: true, // 是否支持列表项选中功能
 filter: false, // 是否支持数据过滤功能
 action: false // 是否支持 表格操作功能
 }, // table 的参数
 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 ? '下架' : '审核中')
 }
 },
 ……
 ], // 需要展示的列
 operates: {
 width: 200,
 fixed: 'right',
 list: [
 {
 label: '编辑',
 type: 'warning',
 show: true,
 icon: 'el-icon-edit',
 plain: true,
 disabled: true,
 method: (index, row) => {
 this.handleEdit(index, row)
 }
 },
 {
 label: '删除',
 type: 'danger',
 icon: 'el-icon-delete',
 show: true,
 plain: false,
 disabled: false,
 method: (index, row) => {
 this.handleDel(index, row)
 }
 }
 ]
 } // 列操作按钮
 }
 },
 methods: {
 // 切换每页显示的数量
 handleSizeChange (size) {
 this.limit = size
 console.log(' this.limit:', this.limit)
 },
 // 切换页码
 handleIndexChange (index) {
 this.page = index
 console.log(' this.page:', this.page)
 },
 // 选中行
 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-->
<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.filter(_x=>_x.show === true).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">
 <el-button :type="btn.type" size="mini" :icon="btn.icon" :disabled="btn.disabled"
 :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 @size-change="handleSizeChange"
 @current-change="handleIndexChange"
 :page-size="pageSize"
 :page-sizes="[10, 20, 50]" :current-page="pageIndex" layout="total,sizes, prev, pager, next,jumper"
 :total="total"></el-pagination>
 <!--endregion-->
 <!--region 数据筛选-->
 <div class="filter-data fix-right" v-show="options.filter" @click="showfilterDataDialog">
 <span>筛选过滤</span>
 </div>
 <!--endregion-->
 <!--region 表格操作-->
 <div class="table-action fix-right" v-show="options.action" @click="showActionTableDialog">
 <span>表格操作</span>
 </div>
 <!--endregion-->
 </div>
</template>
<!--endregion-->
<script>
 export default {
 props: {
 list: {
 type: Array,
 default: []
 }, // 数据列表
 columns: {
 type: Array,
 default: []
 }, // 需要展示的列 === prop:列数据对应的属性,label:列名,align:对齐方式,width:列宽
 operates: {
 type: Array,
 default: []
 }, // 操作按钮组 === label: 文本,type :类型(primary / success / warning / danger / info / text),show:是否显示,icon:按钮图标,plain:是否朴素按钮,disabled:是否禁用,method:回调方法
 total: {
 type: Number,
 default: 0
 }, // 总数
 pageSize: {
 type: Number,
 default: 20
 }, // 每页显示的数量
 otherHeight: {
 type: Number,
 default: 160
 }, // 用来计算表格的高度
 options: {
 type: Object,
 default: {
 stripe: false, // 是否为斑马纹 table
 highlightCurrentRow: false // 是否要高亮当前行
 },
 filter: false,
 action: 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,
 multipleSelection: [] // 多行选中
 }
 },
 mounted () {
 },
 computed: {
 height () {
 return this.$utils.Common.getWidthHeight().height - this.otherHeight
 }
 },
 methods: {
 // 切换每页显示的数量
 handleSizeChange (size) {
 this.$emit('handleSizeChange', size)
 this.pageIndex = 1
 },
 // 切换页码
 handleIndexChange (index) {
 this.$emit('handleIndexChange', index)
 this.pageIndex = index
 },
 // 多行选中
 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>

总结

以上所述是小编给大家介绍的Vue2.5 结合 Element UI 之 Table 和 Pagination 组件实现分页功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

显示全文