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


Posted in Javascript onJanuary 26, 2018

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

由于现在公司管理平台主要运用Element UI,索性就结合组件Table 和 Pagination 封装了一个支持页面切换的Table组件,不??拢?苯由洗?搿?/p>

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 组件实现分页功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
js获取变量
Aug 24 Javascript
DOM精简教程
Oct 03 Javascript
利用CSS、JavaScript及Ajax实现高效的图片预加载
Oct 16 Javascript
AngularJs根据访问的页面动态加载Controller的解决方案
Feb 04 Javascript
jQuery实现气球弹出框式的侧边导航菜单效果
Sep 22 Javascript
AngualrJS中的Directive制作一个菜单
Jan 26 Javascript
vue实现ToDoList简单实例
Feb 07 Javascript
JS中cookie的使用及缺点讲解
May 13 Javascript
JavaScript生成图形验证码
Aug 24 Javascript
vue+swiper实现组件化开发的实例代码
Oct 26 Javascript
微信小程序云开发如何实现数据库自动备份实现
Aug 16 Javascript
Flexible.js可伸缩布局实现方法详解
Nov 13 Javascript
微信小程序实现图片压缩功能
Jan 26 #Javascript
js动态添加表格逐行添加、删除、遍历取值的实例代码
Jan 25 #Javascript
Laravel整合Bootstrap 4的完整方案(推荐)
Jan 25 #Javascript
jquery根据name取得select选中的值实例(超简单)
Jan 25 #jQuery
用jquery获取select标签中选中的option值及文本的示例
Jan 25 #jQuery
利用js给datalist或select动态添加option选项的方法
Jan 25 #Javascript
基于vue.js无缝滚动效果
Jan 25 #Javascript
You might like
php str_replace的替换漏洞
2008/03/15 PHP
Windows7下PHP开发环境安装配置图文方法
2010/05/20 PHP
CodeIgniter图像处理类的深入解析
2013/06/17 PHP
解析php函数method_exists()与is_callable()的区别
2013/06/21 PHP
CentOS6.5 编译安装lnmp环境
2014/12/21 PHP
Laravel5中防止XSS跨站攻击的方法
2016/10/10 PHP
jQuery Ajax文件上传(php)
2009/06/16 Javascript
AlertBox 弹出层信息提示框效果实现步骤
2010/10/11 Javascript
javascript基础之查找元素的详细介绍(访问节点)
2013/07/05 Javascript
javascript计时器事件使用详解
2014/01/07 Javascript
JavaScript操作Cookie详解
2015/02/28 Javascript
JavaScript中Number对象的toFixed() 方法详解
2016/09/02 Javascript
jQuery实现 RadioButton做必选校验功能
2017/06/15 jQuery
JS实现简单的浮动碰撞效果示例
2017/12/28 Javascript
脚手架vue-cli工程webpack的基本用法详解
2018/09/29 Javascript
Vue 指令实现按钮级别权限管理功能
2019/04/23 Javascript
一篇超完整的Vue新手入门指导教程
2020/11/18 Vue.js
详解Django缓存处理中Vary头部的使用
2015/07/24 Python
Django 浅谈根据配置生成SQL语句的问题
2018/05/29 Python
python将.ppm格式图片转换成.jpg格式文件的方法
2018/10/27 Python
python multiprocessing模块用法及原理介绍
2019/08/20 Python
Python学习笔记之字符串和字符串方法实例详解
2019/08/22 Python
在keras中获取某一层上的feature map实例
2020/01/24 Python
Python selenium文件上传下载功能代码实例
2020/04/13 Python
浅谈python出错时traceback的解读
2020/07/15 Python
PyQT5速成教程之Qt Designer介绍与入门
2020/11/02 Python
兰蔻英国官网:Lancome英国
2019/04/30 全球购物
中文专业毕业生自荐信
2013/10/28 职场文书
企业文化理念标语
2014/06/10 职场文书
幼师求职信
2014/06/23 职场文书
2014年教师节座谈会发言稿
2014/09/10 职场文书
2015年度个人思想工作总结
2015/04/08 职场文书
2016年度继续教育学习心得体会
2016/01/19 职场文书
跟班学习心得体会(共6篇)
2016/01/23 职场文书
导游词之云南-元阳梯田
2019/10/08 职场文书
笔记本自带的win11如何跳过联网激活?
2022/04/20 数码科技