参考来源 https://adminpro.iviewui.com/form/advanced-form
需要实现的效果
在开发后台系统时,我们有时候会遇到一些可编辑表格,如下图。
最终需要得到的数据
与此同时后端人员希望我们按照他们要的数据格式拼好并发送请求。
数据实现
接下来笔者将以 vue + iview 为例,提供可编辑列表的思路。
安装
【vue环境】首先,要安装好vue-cli脚手架。或者,你也可以new一个vue实例,在html中写demo。总之,能提供一个vue环境就可。
【iview】接着,得安装好iview,并引入iview的table组件。(建议按需引入)
代码实现
模板代码 <Table :columns="columns" :data="form.profits"/>
逻辑代码
<script>
export default {
data() {
return {
nums: [ '', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十' ],
// 当前编辑项-索引
currentEdit: 0,
// 新增项时,其他项不可编辑
disabled: true,
// 当前编辑项-表单
editForm: {
source: '自身',
merchantProfit: '',
agentProfit: '',
orderProfit: ''
},
form: {
name: '',
profits: [
{
source: '自身',
merchantProfit: '',
agentProfit: '',
orderProfit: ''
}
]
},
columns: [
{
title: '分润来源',
key: 'source'
},
{
title: '分润(万分比/单)',
key: 'orderProfit',
render: (h, { row, index }) => {
if (index === this.currentEdit){
return (<Input v-model={this.editForm.orderProfit} clearable/>)
}
else {
return (<span>{ row.orderProfit }</span>)
}
}
},
{
title: '商户奖励(元/户)',
key: 'merchantProfit',
render: (h, { row, index }) => {
if (index === this.currentEdit){
return (<Input v-model={this.editForm.merchantProfit} clearable/>)
}
else {
return (<span>{ row.merchantProfit }</span>)
}
}
},
{
title: '代理商奖励(元/户)',
key: 'agentProfit',
render: (h, { row, index }) => {
if (index === this.currentEdit){
return (<Input v-model={this.editForm.agentProfit} clearable/>)
}
else {
return (<span>{ row.agentProfit }</span>)
}
}
},
{
title: '操作',
align: 'center',
render: (h, { row, index }) => {
if (index === this.currentEdit) {
return (<div class="ui-table-btns bdLeft">
<span class="green" onClick={() => this.save(index)}>保存</span>
<span v-show={ this.cancelable(row) } onClick={() => this.currentEdit = null}>取消</span>
<span v-show={ this.disabled && row.source !== '自身' } onClick={() => this.remove(index)}>删除</span>
</div>)
}
else {
return (<div class="ui-table-btns bdLeft">
<span class={{ 'grey': this.disabled }} onClick={() => this.edit(row, index)}>编辑</span>
<span class={{ 'grey': this.disabled }} v-show={row.source !== '自身'} onClick={() => this.delete(row.source, index)}>删除</span>
</div>)
}
}
},
]
}
},
mounted(){
if (this.id){
this.pull()
}
},
methods: {
// 获取列表数据(仅为编辑页面时,若为新增数据的页面,则不做处理)
pull() {
const { name, profits } = data
this.form.name = name
this.form.profits = profits.map((o,i) => ({
...o,
source: o.source !== '自身' `下属代理(${this.nums[i]}级)` : o.source,
merchantProfit: o.merchantProfit / 100,
agentProfit: o.agentProfit / 100,
orderProfit: o.orderProfit
}))
this.currentEdit = null
this.disabled = false
},
// 新增项和自身不可取消
cancelable(row){
const check = Object.values(row).every(x => x !== '')
if (!check || this.disabled){
return false
}
return true
},
// 编辑
edit(row, index) {
if (this.disabled) return
const { _index, _rowKey, ...editForm } = row
// console.log(editForm)
this.editForm = editForm
this.currentEdit = index
},
// 保存
save(i) {
const check = Object.values(this.editForm).every(x => x !== '')
const checkNum = Object.entries(this.editForm).filter(([key]) => key !== 'source').every(([key, value]) => !window.isNaN(value) && value >= 0)
if (!check){
this.$Message.warning('请填写完整信息')
return
}
else if(!checkNum){
this.$Message.warning('请输入非负的数字')
return
}
else if (/\./.test(this.editForm.orderProfit)) {
this.$Message.warning('分润只能为整数')
return
}
const nArr = [ ...this.form.profits ]
nArr[i] = this.editForm
this.form.profits = nArr
this.currentEdit = null
this.disabled = false
},
// 删除
delete(source, index) {
if (this.disabled) return
this.$confirm({
content: `确定删除${ source }吗`,
onOk: () => {
this.form.profits.splice(index, 1)
}
})
},
// 删除新增项
remove(index) {
this.form.profits.splice(index, 1)
this.disabled = false
this.currentEdit = null
},
// 新增分润来源
add() {
const i = this.form.profits.length
const editForm = {
source: `下级代理(${ this.nums[i] }级)`,
merchantProfit: '',
agentProfit: '',
orderProfit: ''
}
this.editForm = editForm
this.form.profits.push(editForm)
this.disabled = true
this.currentEdit = i
},
// 进行验证及获取最终数据
submit() {
if (!this.form.name){
this.$Message.warning('请输入配置名称')
return
}
else if(typeof this.currentEdit === 'number') {
this.$Message.warning('请保存完信息再提交')
return
}
const form = {
...this.form,
profits: this.form.profits.map((o, i) => ({
...o,
source: i,
merchantProfit: o.merchantProfit * 100,
agentProfit: o.agentProfit * 100,
orderProfit: o.orderProfit
}))
}
// 最终需要的数据
console.log(this.form)
}
}
}
</script>
-
新增页面时的状态(需保证新增时有至少一条数据)
-
编辑页面的状态