在Vue前端项目中,我这里主要是基于Vue+Element的开发,大多数情况下,我们利用Element的表格组件就可以满足大多数情况的要求,本篇随笔针对表格的展示和编辑处理,综合性的介绍几款表格组件的展示和处理效果,其中包括Element的el-table组件,以及其他第三方类组件,如vue-easytable、vue-willtable,以及vxe-table,针对性的对比相关的差异。

1、el-table表格组件

这个是Element的表格组件,使用参考地址如下:https://element.eleme.cn/#/zh-CN/component/table
这个表格组件也是非常好用的展示数据的组件,提供了很多属性设置,表格列的模板定义可以进行各种各样的转义和处理,是我们使用Element组件经常用到的组件之一。
简单的界面效果如下所示。

它的简单界面代码如下所示,主要就是提供列的定义。

<template>
<el-table :data="tableData" stripe style="width: 100%">
<el-table-column prop="date" label="日期" width="180"> </el-table-column>
<el-table-column prop="name" label="姓名" width="180"> </el-table-column>
<el-table-column prop="address" label="地址"> </el-table-column>
</el-table>
</template>

而数据这是一个对象集合,里面对应各种属性记录,如下所示。

<script>
export default {
data() {
return {
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}]
}
}
}
</script>

不过一般实际使用的表格比这个会复杂很多,会在列之中提供很多转义信息展示,如下界面效果所示

或者

我们来看看表格头部和表格列的相关定义来进行解析。

<el-table v-loading="listLoading" :data="list" border fit stripe highlight-current-row
:header-cell-style="{background:'#eef1f6',color:'#606266'}" @selection-change="selectionChange"
@row-dblclick="rowDbclick" @sort-change="sortChange">

listLoading用来 展示/隐藏 加载中的状态

list则是提供给表格数据处理的数据源

selectionChange这是选中/取消勾选框的事件触发

rowDbclick是双击表格行出现的事件响应

sortChange是排序表头出现的事件处理

另外,表格数据往往涉及到分页信息,那么必须和分页控件一起使用

        <!--分页部分 -->
<div class="block" style="height:70px;">
<el-pagination :current-page="pageinfo.pageindex" :page-size="pageinfo.pagesize" :total="pageinfo.total"
:page-sizes="[10,20,30,40]" layout="total, sizes, prev, pager, next" @size-change="sizeChange"
@current-change="currentChange" />
</div>

其中分页组件中涉及到pageinfo对象,包括当前页码和每页的数据记录数量,以及对每页数据大小变化事件sizeChange、页码变化的事件currentChange的处理。

因此我们在<script>中定义相关的变量和方法。

export default {
components: {}, // 常见组件已经在main.js中挂载
data () {
return {
listLoading: false, // 列表加载状态
list: [], // 页面列表数据
pageinfo: {// 分页条件
pageindex: 1,
pagesize: 20,
total: 0
},
listSelection: [], // 选中记录
sorting: null, // 排序条件

获取数据的事件getlist中,我们主要就是根据条件获取数据记录,并赋值给list对象即可。

而其他相应的事件如下定义所示

    search () { // 查询列表处理
this.pageinfo.pageindex = 1;// 重置为第一页
this.searchForm.pid = null;// 重置选择类型
this.getlist()
},
resetSeachForm (formName) { // 重置查询条件处理
this.$refs[formName].resetFields();
this.search()
},
sortChange ({ column, prop, order }) {
var direction = (order === 'ascending') ? ' ASC' : ' DESC'
this.sorting = !this.isEmpty(prop) ? (prop + direction) : null
this.getlist()
},
sizeChange (val) { // 页面大小变化处理
// console.log(`每页 ${val} 条`);
this.pageinfo.pagesize = val;
this.getlist()
},
currentChange (val) { // 页码变化处理
// console.log(`当前页: ${val}`);
this.pageinfo.pageindex = val;
this.getlist()
},
selectionChange (val) { // 选中记录
this.listSelection = val;
},
rowDbclick (row, column) { // 列表单击处理
var id = row.id
this.showView(id);
},

这样我们就是实现了对数据的分页处理,和相关的事件处理。剩下的就是对记录列内容的转义处理了,这个通过HTML的代码进行处理即可。

常规的内容处理如下所示。

<el-table-column align="center" label="名称" sortable="custom" prop="name" min-width="150">
<template slot-scope="scope">
{{ scope.row.name }}
</template>
</el-table-column>

如果我们需要进行转义,在这里面处理判断就可以了,非常方便。

  <el-table-column align="center" label="可见" sortable="custom" prop="visible" width="80">
<template slot-scope="scope">
<el-tag v-if="scope.row.visible" type="success" effect="dark">可见</el-tag>
<el-tag v-else type="danger" effect="dark">隐藏</el-tag>
</template>
</el-table-column>

或者通过formater的函数进行内容的转义处理。

<el-table-column align="center" label="创建时间" width="160" sortable="custom" prop="createTime"  :formatter="timeFormat" />

也可以使用filter进行内容转义

  <el-table-column align="center" label="商品类型" width="120" prop="ProductType">
<template slot-scope="scope">
<el-tag type="danger"> {{ scope.row.ProductType | productTypeFilter }}</el-tag>
</template>
</el-table-column>

如果我们需要添加表格列的操作处理,那么添加对应的按钮即可,通过获取对应记录的标识,来进行相关记录的操作即可。

  <!--表格行操作按钮 -->
<el-table-column align="center" label="操作" width="110">
<template scope="scope">
<el-row>
<el-button-group>
<el-tooltip effect="light" content="查看" placement="top-start">
<el-button icon="el-icon-search" type="success" circle size="mini"
@click="showView(scope.row.id)" />
</el-tooltip>
<el-tooltip effect="light" content="编辑" placement="top-start">
<el-button icon="el-icon-edit" type="primary" circle size="mini" @click="showEdit(scope.row.id)" />
</el-tooltip>
<el-tooltip effect="light" content="删除" placement="top-start">
<el-button icon="el-icon-delete" type="danger" circle size="mini"
@click="showDelete(scope.row.id)" />
</el-tooltip>
</el-button-group>
</el-row>
</template>
</el-table-column>

Element的表格组件功能虽然很好,不过它的特点是展示处理,并不是很适合进行直接内容的编辑处理,有些人通过变量标识模板的方式控制编辑界面的展示,不过总体太复杂,不方便使用。

2、vue-easytable表格组件

vue-easytable表格组件地址:
npm安装:npm install vue-easytable -S
这个组件相对于Element的表格el-table来说,它的HTML代码比较少,适用于简单快捷的表格数据展示。
简单使用代码如下所示
 <ve-table :columns="columns" :table-data="tableData" />

一般它的使用代码如下所示(配合分页数据展示)

    <ve-table row-key-field-name="id" :checkbox-option="checkboxOption" :columns="columns" :table-data="list"
:fixed-header="true" :border-around="true" :border-x="true" :border-y="true" /> <!--分页部分 -->
<div class="block" style="height:70px;">
<el-pagination :current-page="pageinfo.pageindex" :page-size="pageinfo.pagesize" :total="pageinfo.total"
:page-sizes="[10,20,30,40]" layout="total, sizes, prev, pager, next" @size-change="sizeChange"
@current-change="currentChange" />

常见的界面效果如下所示

一般我们需要在JS中定义列的信息,它的类型可以是expand、checkbox、radio几种之一,默认是字符串方式。

当前列类型: "expand":行展开;"checkbox":行多选;"radio":行单选

      columns: [// 表列定义
{
field: '',
key: 'a',
type: 'checkbox',
title: '',
width: 50,
align: 'center'
},
{
field: 'name',
key: 'name',
title: '姓名',
width: 120,
columnAlign: 'center'
},

这个列的定义除了field外,还需要一个Key的标识,不能为空,一般保留位field的值即可。

如果我们需要进行内容的转义处理,可以使用 renderBodyCell 函数进行转义处理,如下所示。

        {
field: 'sex',
key: 'sex',
title: '性别',
width: 120,
columnAlign: 'center',
renderBodyCell: ({ row, column, rowIndex }, h) => {
const text = row[column.field];
// return <input style="width:100%" value={text}></input>;
let html = null
if (text === '男') {
html = <el-tag type='primary'>{text}</el-tag>
} else {
html = <el-tag type='success'>{text}</el-tag>
}
return (
<div>
{html}
</div>
)
}
},

数据的处理,和我们前面介绍的类似,就是通过分页条件的方式进行查询分页,获得数据后赋值给对应列表即可。

      // 获取列表,绑定到模型上,并修改分页数量
this.listLoading = true
testUser.GetAll(param).then(data => {
console.log(data.result.items) this.list = data.result.items
this.pageinfo.total = data.result.totalCount
this.listLoading = false
})

通过 row-key-field-name="id" :checkbox-option="checkboxOption" 代码的处理,可以实现选中记录的操作。

  checkboxOption: {
// row select事件
selectedRowChange: ({ row, isSelected, selectedRowKeys }) => {
console.log(row, isSelected, selectedRowKeys);
},
// selected all事件
selectedAllChange: ({ isSelected, selectedRowKeys }) => {
console.log(isSelected, selectedRowKeys);
}
},

这个表格组件也主要是进行展示,没有直接编辑的处理操作,不过它的特点是快速展示数据,转义的话操作起来会费劲一些,它主要就是通过jsx的方式进行转义处理的,感觉没有在HTML上直接判断的快捷明了。

 

3、vue-willtable表格组件(可直接编辑)

 以上两个表格组件,都没有涉及到编辑的操作,有时候我们在一些表格中希望给客户直接录入数据的场景。
如果采用el-table的方式来处理,非常不直观,也不易处理,因此引入第三方组件的方式来实现数据的直接录入就比较好 了。

vue-willtable表格组件地址:https://github.com/KevinMint55/vue-willtable

官方案例界面效果如下所示。

表格提供日期,数值、下拉列表,字符串等几种常见方式的录入。

总体上录入没有什么问题,不过对于组件的更新好像有时候有些问题,毕竟github上星星不是很多的项目。

我在这个基础上进行了案例的测试,界面效果如下所示。

主从表展示界面效果

以及表格查询分页处理和录入界面效果

    <div class="willtable_wrapper">
<vue-willtable ref="table" v-model="list" :columns="columns" :row-height="38" :cell-class-name="cellClassName" />
</div>

字段定义的JS代码如下所示。

获取数据的JS代码如下所示

  // 获取列表,绑定到模型上,并修改分页数量
this.listLoading = true
testUser.GetAll(param).then(data => {
this.$refs.table.setData(data.result.items) this.pageinfo.total = data.result.totalCount
this.listLoading = false
})

不过分页的话,切换页面大小会导致刷新显示有些问题 ,部分空白,首次显示倒是没有问题。

 

4、vxe-table表格组件(可直接编辑)

vxe-table是github上星星超过4k+的开源组件,这个表格不论是展示数据,以及编辑的处理,都堪称大能之作,非常方便强大。

vxe-table地址:

https://xuliangzhan_admin.gitee.io/vxe-table/#/table/start/install

https://github.com/x-extends/vxe-table

我们来看看它的常规使用代码,以及界面效果

如果需要录入新记录,通事件处理添加一个行即可。

vxe-table的使用HTML代码和Element的el-table类似,通过HTML声明的方式进行定义,如下所示。

<vxe-table ref="xTable" border show-overflow keep-source resizable show-overflow :data="list"
:edit-config="{trigger: 'click', mode: 'row', showStatus: true}">
<vxe-column type="seq" width="60" />
<vxe-column field="name" title="姓名" :edit-render="{name: 'input', attrs: {type: 'text'}}" /> <vxe-column field="sex" title="性别" :edit-render="{name: '$select', options: sexList}" /> <vxe-column field="emailAddress" title="邮件地址"
:edit-render="{name: 'input', attrs: {type: 'text', placeholder: '请输入邮件地址'}}" /> <vxe-column field="marriage" title="婚姻状况"
:edit-render="{name: '$select', options: marriageList, props: {multiple: false}}" /> <vxe-column field="status" title="状态"
:edit-render="{name: '$select', options: StatusList, props: {multiple: false}}" /> <vxe-column field="height" title="身高" :edit-render="{name: '$input', props: {type: 'float', digits: 2}}" /> <vxe-column field="birthDate" title="出生日期"
:edit-render="{name: '$input', props: {type: 'date', placeholder: '请选择日期'}}" :formatter="formatDate" />
</vxe-table>

而数据的获取展示方式,和上面代码操作一样

      // 获取列表,绑定到模型上,并修改分页数量
this.listLoading = true
testUser.GetAll(param).then(data => {
console.log(data.result.items) this.list = data.result.items
this.pageinfo.total = data.result.totalCount
this.listLoading = false
})

其实我们主要关注它的数据的新增,以及保存处理即可,插入或者移除记录的处理如下代码所示。

   async insertEvent () {
const $table = this.$refs.xTable
const newRecord = {}
const { row: newRow } = await $table.insert(newRecord)
await $table.setActiveRow(newRow)
},
async removeSelectEvent () {
const $table = this.$refs.xTable
await $table.removeCheckboxRow()
},
async removeRowEvent (row) {
const $table = this.$refs.xTable
await $table.remove(row)
},

如果是保存,那么需要获取数据记录的更新、删除、新增几个集合的情况,然后统一通过后端进行辨别处理即可。

    async saveEvent () {
const $table = this.$refs.xTable
const { insertRecords, removeRecords, updateRecords } = $table.getRecordset()
if (insertRecords.length <= 0 && removeRecords.length <= 0 && updateRecords.length <= 0) {
this.msgSuccess('数据未改动!')
return
}
const errMap = await $table.validate().catch(errMap => errMap)
if (errMap) {
return
}
this.listLoading = true
try {
const body = { insertRecords, removeRecords, updateRecords }
console.log(body)
// /await XEAjax.post('https://api.xuliangzhan.com:10443/demo/api/pub/save', body)
// await this.loadList()
this.msgSuccess(`操作成功,新增 ${insertRecords.length} 条,更新 ${updateRecords.length} 条,删除 ${removeRecords.length} 条`)
} catch (e) {
if (e && e.message) {
this.msgSuccess(e.message)
}
}
this.listLoading = false
},

通过引用对象的 getRecordset 我们可以获得相关新增、更新、删除的集合,然后通过自己的逻辑处理数据即可。

该表格组件提供了很多方便的处理案例,我们可以通过学习方式进行参考即可。

以上就是几款表格组件的效果,对比它们,一般来说,我们还是倾向于使用el-table的内置表格组件来展示数据,而且也可以通过我们的代码生成工具Database2sharp进行vue界面的快速生成,然后微调即可,而对于数据直接编辑的处理,则建议通过使用vxe-table的组件的方式进行处理,它提供了非常多强大的功能,可以满足我们直接录入数据的处理操作。

在Vue前端界面中,几种数据表格的展示处理,以及表格编辑录入处理操作。的更多相关文章

  1. 在Vue前端项目中,附件展示的自定义组件开发

    在Vue前端界面中,自定义组件很重要,也很方便,我们一般是把一些通用的界面模块进行拆分,创建自己的自定义组件,这样操作可以大大降低页面的代码量,以及提高功能模块的开发效率,本篇随笔继续介绍在Vue&a ...

  2. 在Web界面中实现Excel数据大量导入的处理方式

    在早期Bootstrap框架介绍中,我的随笔<结合bootstrap fileinput插件和Bootstrap-table表格插件,实现文件上传.预览.提交的导入Excel数据操作流程> ...

  3. Vue单页面中进行业务数据的上报

    为什么要在标题里加上一个业务数据的上报呢,因为在咱们前端项目中,可上报的数据维度太多,比如还有性能数据.页面错误数据.console捕获等.这里我们只讲解业务数据的埋点. 业务数据的上报主要分为: 各 ...

  4. iOS中几种数据持久化方案

    概论 所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据.在iOS开发中,有很多数据持久化的方案,接下来我将尝试着介绍一下5种方案: plist文件(属性列表) ...

  5. iOS中几种数据持久化方案:我要永远地记住你!

    http://www.cocoachina.com/ios/20150720/12610.html 作者:@翁呀伟呀 授权本站转载 概论 所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启 ...

  6. 论MySQL数据库中两种数据引擎的差别

    InnoDB和MyISAM是在使用MySQL最常用的两个表类型,各有优缺点,视具体应用而定. 基本的差别为: MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持. MyISAM类型的表强 ...

  7. [ 记录 ] Vue 对象数组中一项数据改变,页面不更新

    问题描述:将data中数据列表渲染到页面,循环生成 el-switch,点击页面中 el-switch 后数组中某项值改变,但是页面不更新 数据格式如下 export default{ data(){ ...

  8. vue向数组中动态添加数据

    vue中数据更新通过v-model实现,向数组中添加数据通过push()实现,向shortcuts数组中动态添加newShortcut对象中的title和action this.shortcuts.p ...

  9. Netty源码之解码中两种数据积累器(Cumulator)的区别

    上一篇随笔中已经介绍了解码核心工作流程,里面有个数据积累器的存在(Cumulator),其实解码中有两种Cumulator,那他们的区别是什么呢? 还是先打开ByteToMessageDecoder的 ...

随机推荐

  1. EF架构封装类

    http://www.woxihuan.com/46528208/1323334777088641.shtml http://www.ediclot.com/archives/2368 http:// ...

  2. django安装xadmin

    环境:pycharm  django1.11.20  python2.7(根据网络上的资料,自己整理实现) 下载:https://github.com/sshwsfc/xadmin/tree/mast ...

  3. python二级 第9套

    1. prInt.默认输出空格 2. 我的这种想法也行不通啊 format() 一次只能有一个未知量 2. 分割的结果就是列表 3. 对比"大学"    上一套的split('&q ...

  4. P2611-[ZJOI2012]小蓝的好友【Treap,扫描线】

    正题 题目链接:https://www.luogu.com.cn/problem/P2611 题目大意 \(r*c\)的网格上有\(n\)个标记点,然后求有多少个矩形包含至少一个标记点. \(1\le ...

  5. IDEA破解方法:重新刷新到30天【支持正版】

    IDEA破解方法:重新刷新到30天[支持正版] 步骤: 导入plugins.zhile.io 进入File-->Settings-->Plugins 点设置(齿轮符号)-->Mana ...

  6. amber模拟kcl水溶液

    最近刚开始学习amber软件,看网上的教程勉强知道怎么操作这个amber了.就暂时跑了个分子动力学,其他的啥也没处理.先把我的操作过程记录下来吧,免得日后忘记. 一.构建kcl.pdb结构 利用Gau ...

  7. 【原创】xenomai 在X86平台下中断响应时间测试

    1.中断响应时间 实时操作系统的意义就在于能够在确定的时间内处理各种突发的事件,而中断这些事件.系统抢占调度的触发点,因而衡量嵌入式实时操作系统的最主要.最具有代表性的性能指标参数无疑是中断响应时间. ...

  8. BurpSuite 功能概览

    简介 写作思想:相比较具体介绍某个功能的用法.会更加侧重于介绍 Burp 提供哪些功能.这样好处是在比较复杂的测试场景,如果Burp 刚好提供对应的功能,就不用花费精力造轮子了. 而需要掌握具体操作方 ...

  9. 函数式编程 —— 将 JS 方法函数化

    前言 JS 调用方法的风格为 obj.method(...),例如 str.indexOf(...),arr.slice(...).但有时出于某些目的,我们不希望这种风格.例如 Node.js 的源码 ...

  10. $\text {FWT}$学习笔记

    \(\text {FWT}\) 学习笔记 正常项的\(\text {FWT}\) 在\(\text {OI}\)中,我们经常会碰到这种问题: 给出一个长度为\(n\)的序列\(a_{1,2,...,n ...