实现效果:
因为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官方也有给文档,但是超级麻烦,代码量还超级多,改编了一下
如图:
这里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 "确定删除该信息" 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嵌套表格及表格内部编辑的用法说明就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]