ant design vue嵌套表格及表格内部编辑的用法说明


Posted in Javascript onOctober 28, 2020

实现效果:

ant design vue嵌套表格及表格内部编辑的用法说明

因为pro手脚架中封装的s-table不支持expand和expandedRowsChange事件,无法实现根据展开节点获取其内部数据的需求,因此直接使用a-table组件

表格外层可以翻页,查询携带页码参数

<a-table
size="default"
rowKey="dict_id" //根据自己数据内部关键针设定
ref="table"
@expandedRowsChange="expandedRowsChange"
@expand="expand" // 展开表格节点操作
@change="change" // 外层表格中排序,翻页,修改页面数量等操作
:expandedRowKeys="expandedRowKeys" // 操作展开的节点
:pagination="pagination" // 页码参数
:columns="columns" // 表头
:dataSource="loadData" // 数据
>
<a-table
size="default"
style="margin-bottom:0;"
rowKey="key"
slot="expandedRowRender" // 以内层方式展现
:columns="innerColumns"
:dataSource="data"
:pagination="false"
:loading="innerloading"
@change="innerhandleChange"
>
<template v-for="(col, i) in ['item_text', 'item_value', 'item_checked', 'item_remark', 'item_sort', 'item_status']" :slot="col" slot-scope="text, record">
<a-input
:key="col"
v-if="record.editable"
style="margin: -5px 0"
:value="text"
:placeholder="innerColumns[i].title"
@change="e => handleChange(e.target.value, record.key, col)"
/>
<template v-else>{{ text }}</template>
</template> // 内部表格可编辑模板
<template slot="operation" slot-scope="text, record">
<template v-if="record.editable">
<span v-if="record.isNew">
<a @click="saveRow(record)">添加</a>
<a-divider type="vertical" />
<a-popconfirm title="是否要删除此行?" @confirm="remove(record.key)">
<a>删除</a>
</a-popconfirm>
</span>
<span v-else>
<a @click="saveRow(record)">保存</a>
<!-- <a-divider type="vertical" />
<a @click="cancel(record.key)">取消</a> -->
</span>
</template> // 内部表格新增模板
<span v-else>
<a @click="toggle(record)">编辑</a>
</span>
</template>
</a-table>
<div
slot="expandedRowRender"
style="margin: 0">
<a-button style="width: 100%; margin-top: 16px; margin-bottom: 8px" type="dashed" icon="plus" @click="newMember">新增属性</a-button>
</div>
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)">编辑</a>
</span>
</a-table>

主要数据:

expandedRowKeys: [],
  // 表头
  columns: [
  {
   title: '字典编码',
   dataIndex: 'dict_code'
  },
  {
   title: '字典名称',
   dataIndex: 'dict_name'
  },
  {
   title: '状态',
   dataIndex: 'dict_status'
  },
  {
   title: '字典描述',
   dataIndex: 'dict_remark'
  }, {
   title: '操作',
   width: '150px',
   dataIndex: 'action',
   scopedSlots: { customRender: 'action' }
  }
  ],
  loadData: [],
  innerColumns: [
  {
   title: '字段名',
   dataIndex: 'item_text',
   key: 'item_text',
   width: '15%',
   scopedSlots: { customRender: 'item_text' }
  },
  {
   title: '字段值',
   dataIndex: 'item_value',
   key: 'item_value',
   width: '15%',
   scopedSlots: { customRender: 'item_value' }
  },
  {
   title: '默认选中(0:否,1:是)',
   dataIndex: 'item_checked',
   key: 'item_checked',
   width: '10%',
   scopedSlots: { customRender: 'item_checked' }
  },
  {
   title: '备注',
   dataIndex: 'item_remark',
   key: 'item_remark',
   width: '20%',
   scopedSlots: { customRender: 'item_remark' }
  },
  {
   title: '排序号',
   dataIndex: 'item_sort',
   key: 'item_sort',
   width: '10%',
   sorter: true,
   scopedSlots: { customRender: 'item_sort' }
  },
  {
   title: '状态(1:正常,2:异常)',
   dataIndex: 'item_status',
   key: 'item_status',
   width: '10%',
   scopedSlots: { customRender: 'item_status' }
  },
  {
   title: '操作',
   key: 'action',
   scopedSlots: { customRender: 'operation' }
  }
  ],
  data: [],
  innerloading: false,
  parameter: {
  pageNo: 1,
  pageSize: 10
  },
  // 排序参数
  sortedInfo: null,
  pagination: {
  total: 1,
  current: 1,
  showTotal: total => `共 ${total} 条记录 第 ${this.pagination.current} / ${Math.ceil(total / this.pagination.pageSize)} 页`,
  showQuickJumper: true,
  showSizeChanger: true,
  pageSize: 10
  }

初始进入页面时,需要获取外层表格

使用初始参数parameter请求第一页数据,从返回数据中对pagination重置翻页组件内部参数,主要有当前页,页码总量,页码大小

getDictList(this.parameter)
  .then(res => {
   if (res.code === '200') {
   console.log(res)
   this.loadData = res.data
   this.pagination.total = res.totalCount
   this.pagination.current = res.pageNo
   this.pagination.pageSize = res.pageSize
   } else {
   this.$message.error(res.message)
   }
  })

展开外层数据节点获取内部数据:

expand (expanded, record) {
  this.expandedRowKeys = [] // 重置展开节点,只展开当前点击的节点(内部数据调用模板,无法做到同时几个内层表格数据直接缓存在页面)
  if (expanded) {
  this.expandedRowKeys = [record.dict_id]
  this.getDictItem() // 获取表格内部数据
  }
  console.log(expanded, record)
 },
// 展开节点后获取内部表格数据
getDictItem (obj) {
  let searchparam = { dict_id: this.expandedRowKeys[0] }
  if (obj) { // 内部表格除了根据其父节点id查找的条件外,还支持排序,因此需要整合排序参数
  searchparam = Object.assign(searchparam, obj)
  }
  this.innerloading = true
  getDictItemList(searchparam).then(res => {
  if (res.code === '200') {
   this.data = res.data
   this.innerloading = false
  } else {
   this.$message.error(res.message)
  }
  })
 },
// 外层表格操作
 change (pagination, filters, sorter) { // 对页面大小,筛选,排序等条件修改后重新查询数据
  this.pagination = pagination
  this.parameter.pageNo = pagination.current
  this.parameter.pageSize = pagination.pageSize
  this.getDict()
  console.log('pagination', pagination)
  console.log('filters', filters)
  console.log('sorter', sorter)
 },
 /* 内层表格操作 */
 innerhandleChange (pagination, filters, sorter) {
  console.log('Various parameters', pagination, filters, sorter)
  this.sortedInfo = {
  sortField: sorter.field,
  sortOrder: sorter.order
  }
  this.getDictItem(this.sortedInfo)
 },

至此,展示功能已经几乎做完啦,现在是内部表格的编辑与新增功能

handleChange (value, key, column) { // 实时更新表格中各个输入框的状态
  const newData = [...this.data]
  const target = newData.filter(item => key === item.key)[0]
  if (target) {
  target[column] = value
  this.data = newData
  }
 },
 toggle (data) { // 切换输入框与文本状态,实现展示与编辑功能
  const target = this.data.filter(item => item.key === data.key)[0]
  target.editable = !target.editable
  console.log(this.data)
 },
 newMember () { // 新增内容后的数据字段
  this.data.push({
  'item_text': '',
  'item_value': '',
  'item_checked': '',
  'item_remark': '',
  'item_sort': '',
  'item_status': '',
  key: this.data.length,
  editable: true,
  isNew: true
  })
 },
 saveRow (record) {
  this.innerloading = true
  if (!record.item_text || !record.item_value) { // 对必填项进行管控
  this.innerloading = false
  this.$message.error('请至少填写填写字段名和字段值。')
  return
  }
  record.item_checked = record.item_checked || 0 // 设置默认值
  record.item_sort = record.item_sort || 1
  record.item_status = record.item_status || 1
  record.dict_id = this.expandedRowKeys[0]
  if (record.item_id) { // 修改
  updateItem(record).then(res => {
   if (res.code === '200') {
   this.$message.success(res.message)
   this.getDictItem() // 修改成功后重新获取当前内部表格数据
   } else {
   this.$message.error(res.message)
   }
  })
  } else {
  addItem(record).then(res => {
   if (res.code === '200') {
   this.$message.success(res.message)
   this.getDictItem()
   } else {
   this.$message.error(res.message)
   }
  })
  }
 },
 cancel (key) {
  const target = this.data.filter(item => item.key === key)[0]
  target.editable = false
 },
 remove (key) {
  const newData = this.data.filter(item => item.key !== key)
  this.data = newData
 },
 /* 内层表格操作结束 */

外层表格与内存表格数据示例:

{
 "success": true,
 "code": "200",
 "message": "分页查询成功",
 "data": [{
 "dict_id": 1,
 "dict_code": "common_org_type",
 "dict_name": "机构类别",
 "dict_pid": null,
 "dict_status": 1,
 "dict_remark": "机构类别"
 }, {
 "dict_id": 2,
 "dict_code": "common_user_type",
 "dict_name": "人员类别",
 "dict_pid": null,
 "dict_status": 1,
 "dict_remark": "人员类别"
 }, {
 "dict_id": 48,
 "dict_code": "cdsfcsdcf",
 "dict_name": "修改属性1",
 "dict_pid": null,
 "dict_status": 1,
 "dict_remark": ""
 }, {
 "dict_id": 49,
 "dict_code": "bugbugbug",
 "dict_name": "有字典id",
 "dict_pid": null,
 "dict_status": 1,
 "dict_remark": ""
 }, {
 "dict_id": 50,
 "dict_code": "1",
 "dict_name": "名称",
 "dict_pid": null,
 "dict_status": 1,
 "dict_remark": "1"
 }, {
 "dict_id": 51,
 "dict_code": "1",
 "dict_name": "1",
 "dict_pid": null,
 "dict_status": 1,
 "dict_remark": null
 }, {
 "dict_id": 52,
 "dict_code": "1",
 "dict_name": "1",
 "dict_pid": null,
 "dict_status": 1,
 "dict_remark": null
 }, {
 "dict_id": 53,
 "dict_code": "1",
 "dict_name": "1",
 "dict_pid": null,
 "dict_status": 1,
 "dict_remark": null
 }, {
 "dict_id": 54,
 "dict_code": "1",
 "dict_name": "1",
 "dict_pid": null,
 "dict_status": 1,
 "dict_remark": ""
 }, {
 "dict_id": 55,
 "dict_code": "dbhasuiuh",
 "dict_name": "测试字典1",
 "dict_pid": null,
 "dict_status": 1,
 "dict_remark": "备注"
 }],
 "totalCount": 11,
 "pageNo": 1,
 "pageSize": 10,
 "totalTag": 1
}
{
 "success": true,
 "code": "200",
 "message": "查询成功",
 "data": [{
 "item_id": 2,
 "dict_id": 1,
 "item_text": "外部",
 "item_value": "2",
 "item_status": 1,
 "item_sort": 2,
 "item_remark": null,
 "item_checked": 1,
 "editable": 0 // 写死就行了 一定要有 用于内部表格编辑功能
 }, {
 "item_id": 1,
 "dict_id": 1,
 "item_text": "内部",
 "item_value": "1",
 "item_status": 1,
 "item_sort": 1,
 "item_remark": "1",
 "item_checked": 1,
 "editable": 0
 }]
}

补充知识:ant design Table可编辑的单元格改进版

antd官方也有给文档,但是超级麻烦,代码量还超级多,改编了一下

如图:

ant design vue嵌套表格及表格内部编辑的用法说明

这里table的columns的写法,如下:

const columns2 = [
{
title: '尺寸名称',
dataIndex: 'name',
filterDropdown: true,
filterIcon: <Icon type="edit"/>,
render: () => <Input />,
},
{
title: '标准尺寸',
dataIndex: 'standard',
filterDropdown: true,
filterIcon: <Icon type="edit"/>,
render:() => <Input />,
},
{
title: '上偏差',
dataIndex: 'upper_deviation',
filterDropdown: true,
filterIcon: <Icon type="edit"/>,
render:() => <Input />,
},
{
title: '下偏差',
dataIndex: 'lower_deviation',
filterDropdown: true,
filterIcon: <Icon type="edit"/>,
render: () => <Input />,
},
{
title: '工序',
dataIndex: 'procedure',
filterDropdown: true,
filterIcon: <Icon type="edit"/>,
render: () => 
<Select>
  <Option value='1'>1</Option>  
  <Option value='2'>2</Option> 
</Select>
},
{
title: '操作',
dataIndex: 'operation',
render: (text, record) => (
this.state.size.length >= 1
? (
<Popconfirm title="确定删除该信息?" onConfirm={() => this.handleDelete(record.key)}>
<a href="javascript:;">删除</a>
</Popconfirm>
) : null
),
}
];

其中

filterDropdown: true,

filterIcon: <Icon type="edit"/>,

这两个是用于给表头添加图标,不需要可以不写

实现可编辑表格最重要的是吧这个表格所有字段都变成可控字段,这样就可以实现对表格数据的提交的基本操作

就拿我这里面的尺寸名称来说,这个字段叫name ,这里的render就要修改成render: (text, record) => <Input value={text} onChange={(e) => this.handleChange({name: e.target.value}, record)}/>,

这里参数text可以理解为 input的初始值,onChange事件是吧这个input变成可控的组件,handleChange这里有两个参数,这里“”name: e.target.value“”必须要这么传,目的是把改组件的值跟name进行绑定。

handleChange 方法

handleChange = (value, record) => {
for (var i in value) {
record[i] = value[i];//这一句是必须的,不然状态无法更改
this.setState({
size: this.state.size.map((item, key) => item.key == record.key ? {...item, [i]: value[i]} : item)
})
}
}

这里我把这个可编辑表格的值存在state中的size中,通过key进行匹配(这里key代表我这个表格的rowkey,也就是用来区分行数据的一个标识),然后修改指定行的指定数据,通过改变state中的size更新视图,同时吧更改的数据替换掉原来的 这就实现了对表格数据的实时监听,同时表格的所有数据存在了state中的size中,想要获取表格数据直接用this.state.size即可。

(这里需要注意的时,如果把表格中的某个字段,比如说name设置成表格的rowkey,就会发生name字段只能输入单个字符就会失去焦点的情况)

以上这篇ant design vue嵌套表格及表格内部编辑的用法说明就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
dess中一个简单的多路委托的实现
Jul 20 Javascript
javascript改变position值实现菜单滚动至顶部后固定
Jan 18 Javascript
append和appendTo的区别以及appendChild用法
Dec 24 Javascript
canvas绘图不清晰的解决方案
Feb 28 Javascript
vue.js开发环境安装教程
Mar 17 Javascript
客户端(vue框架)与服务器(koa框架)通信及服务器跨域配置详解
Aug 26 Javascript
JS设计模式之数据访问对象模式的实例讲解
Sep 30 Javascript
AngularJS实现的生成随机数与猜数字大小功能示例
Dec 25 Javascript
vue实现组件之间传值功能示例
Jul 13 Javascript
React降级配置及Ant Design配置详解
Dec 27 Javascript
微信小程序实现watch监听
Jun 04 Javascript
react 项目中引入图片的几种方式
Jun 02 Javascript
解决ant design vue 表格a-table二次封装,slots渲染的问题
Oct 28 #Javascript
ant design vue中表格指定格式渲染方式
Oct 28 #Javascript
vue实现一个矩形标记区域(rectangle marker)的方法
Oct 28 #Javascript
ant design vue datepicker日期选择器中文化操作
Oct 28 #Javascript
微信小程序picker组件两列关联使用方式
Oct 27 #Javascript
解决ant Design中this.props.form.validateFields未执行的问题
Oct 27 #Javascript
解决antd Form 表单校验方法无响应的问题
Oct 27 #Javascript
You might like
PHP+AJAX实现无刷新注册(带用户名实时检测)
2007/01/02 PHP
php 结果集的分页实现代码
2009/03/10 PHP
php的urlencode()URL编码函数浅析
2011/08/09 PHP
PHP中读写文件实现代码
2011/10/20 PHP
mysql desc(DESCRIBE)命令实例讲解
2016/09/24 PHP
php实现的生成迷宫与迷宫寻址算法完整实例
2017/11/06 PHP
自写的利用PDO对mysql数据库增删改查操作类
2018/02/19 PHP
jQuery中:input选择器用法实例
2015/01/03 Javascript
JQuery替换DOM节点的方法
2015/06/11 Javascript
JavaScript实现文字跟随鼠标特效
2015/08/06 Javascript
Javascript控制div属性动态变化实例分析
2015/10/08 Javascript
jQuery form插件的使用之处理server返回的JSON, XML,HTML数据
2016/01/26 Javascript
js replace(a,b)之替换字符串中所有指定字符的方法
2016/08/17 Javascript
JS点击某个图标或按钮弹出文件选择框的实现代码
2016/09/27 Javascript
修改 bootstrap table 默认detailRow样式的实例代码
2017/07/21 Javascript
微信小程序switch组件使用详解
2018/01/31 Javascript
javascript少儿编程关于返回值的函数内容
2018/05/27 Javascript
vue如何安装使用Quill富文本编辑器
2018/09/21 Javascript
详解Vue后台管理系统开发日常总结(组件PageHeader)
2019/11/01 Javascript
微信小程序实现滑动操作代码
2020/04/23 Javascript
javascript实现时钟动画
2020/12/03 Javascript
用Python实现协同过滤的教程
2015/04/08 Python
python简单实现刷新智联简历
2016/03/30 Python
Django实现celery定时任务过程解析
2020/04/21 Python
python实现批处理文件
2020/07/28 Python
python3实现名片管理系统(控制台版)
2020/11/29 Python
世界上最大的网络主机公司:1&1
2016/10/12 全球购物
日本索尼音乐商店:Sony Music Shop
2018/07/17 全球购物
请写出一段Python代码实现删除一个list里面的重复元素
2015/12/29 面试题
教师岗位职责
2013/11/17 职场文书
毕业生写求职信的要点
2014/03/04 职场文书
国家励志奖学金个人先进事迹材料
2014/05/04 职场文书
党的群众路线学习笔记
2014/11/06 职场文书
2014年纪检部工作总结
2014/11/12 职场文书
2015年文明创建工作总结
2015/04/30 职场文书
创业计划书之家政服务
2019/09/18 职场文书