优化(todo): 添加/更新/删除/状态切换加loading+乐观更新,修复Switch类型抛错
CI/CD Deploy (Web) / 构建前端镜像并部署 (push) Successful in 19s
CI/CD Deploy (Web) / 构建前端镜像并部署 (push) Successful in 19s
This commit is contained in:
+102
-36
@@ -27,7 +27,10 @@
|
||||
:data="dataList"
|
||||
:loading="tableLoading">
|
||||
<template slot-scope="{ row }" slot="status">
|
||||
<i-switch :value="row.status === 1" true-value="1" false-value="0"
|
||||
<!-- value 必须与 true-value/false-value 同类型(都是数字),否则组件内部会抛
|
||||
'Value should be trueValue or falseValue.' 且状态不更新 -->
|
||||
<i-switch :value="row.status" :true-value="1" :false-value="0"
|
||||
:loading="!!rowLoading[row.id]"
|
||||
@on-change="val => updateStatus(row, val)">
|
||||
<span slot="open">完成</span>
|
||||
<span slot="close">未完成</span>
|
||||
@@ -49,7 +52,7 @@
|
||||
:transfer="true"
|
||||
@on-ok="toDelete(index)"
|
||||
>
|
||||
<Button type="error" size="small" icon="md-trash">删除</Button>
|
||||
<Button type="error" size="small" icon="md-trash" :loading="!!rowLoading[row.id]">删除</Button>
|
||||
</Poptip>
|
||||
</template>
|
||||
</Table>
|
||||
@@ -200,6 +203,7 @@ export default {
|
||||
addModal: false, // 添加
|
||||
editModal: false, // 编辑
|
||||
submitLoading: false,
|
||||
rowLoading: {}, // 行级 loading:{ 待办id: true },用于开关与删除按钮
|
||||
formItem: {
|
||||
id: '',
|
||||
title: '',
|
||||
@@ -214,18 +218,27 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getDataList () {
|
||||
/**
|
||||
* 拉取列表
|
||||
* @param {Boolean} silent 静默刷新:不显示表格 loading,用于乐观更新后的后台同步
|
||||
*/
|
||||
getDataList (silent) {
|
||||
let temp = JSON.parse(JSON.stringify(this.pageParam))
|
||||
let data = objectUtil.trimJoin(temp, this.search)
|
||||
this.tableLoading = true
|
||||
if (!silent) {
|
||||
this.tableLoading = true
|
||||
}
|
||||
const closeLoading = () => {
|
||||
this.tableLoading = false
|
||||
}
|
||||
getDataList(data).then(res => {
|
||||
let page = res.data.data
|
||||
this.pageTotal = page.total
|
||||
this.dataList = page.records
|
||||
// 延迟300毫秒,给它更流畅的感觉
|
||||
setTimeout(() => {
|
||||
this.tableLoading = false
|
||||
}, 300)
|
||||
closeLoading()
|
||||
}).catch(() => {
|
||||
// 出错也要复位 loading,否则表格一直转圈
|
||||
closeLoading()
|
||||
})
|
||||
},
|
||||
toAdd () {
|
||||
@@ -267,53 +280,112 @@ export default {
|
||||
let data = Object.assign({}, this.formItem)
|
||||
// DatePicker 绑定的是 Date 对象,后端按 yyyy-MM-dd 字符串接收
|
||||
data.dueDate = this.formatDate(this.formItem.dueDate)
|
||||
if (this.addModal) { // 添加
|
||||
add(data).then(res => {
|
||||
this.$Message.success('添加成功!')
|
||||
this.refresh()
|
||||
this.getDataList()
|
||||
})
|
||||
} else { // 编辑
|
||||
update(data).then(res => {
|
||||
this.$Message.success('编辑成功!')
|
||||
this.refresh()
|
||||
this.getDataList()
|
||||
})
|
||||
}
|
||||
this.cancel()
|
||||
const isAdd = this.addModal
|
||||
// 按钮转圈:公网穿透链路有延迟,没有反馈会像卡住
|
||||
this.submitLoading = true
|
||||
const req = isAdd ? add(data) : update(data)
|
||||
req.then(res => {
|
||||
// 编辑走本地合并,改完立刻看到结果,不等服务端回包
|
||||
if (!isAdd) {
|
||||
this.mergeRow(data)
|
||||
}
|
||||
this.$Message.success(isAdd ? '添加成功!' : '编辑成功!')
|
||||
// 请求成功后再关弹窗,避免"点了没反应"
|
||||
this.modal = false
|
||||
this.resetForm()
|
||||
this.submitLoading = false
|
||||
// 新增的行 id 由服务端生成,静默拉一次同步(不显示表格 loading)
|
||||
if (isAdd) {
|
||||
this.getDataList(true)
|
||||
}
|
||||
}).catch(() => {
|
||||
this.submitLoading = false
|
||||
this.$Message.error(isAdd ? '添加失败,请重试' : '编辑失败,请重试')
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
/** 把提交的字段合并进当前列表对应行,实现即时更新 **/
|
||||
mergeRow (data) {
|
||||
let row = this.dataList.find(item => String(item.id) === String(data.id))
|
||||
if (!row) {
|
||||
return
|
||||
}
|
||||
row.title = data.title
|
||||
row.status = data.status
|
||||
row.priority = data.priority
|
||||
row.dueDate = data.dueDate
|
||||
row.remark = data.remark
|
||||
},
|
||||
cancel () {
|
||||
// Modal cancel
|
||||
// Modal cancel:只关弹窗并复位表单,不清空搜索条件与分页
|
||||
this.modal = false
|
||||
this.refresh()
|
||||
this.resetForm()
|
||||
},
|
||||
/** 复位弹窗表单 **/
|
||||
resetForm () {
|
||||
this.formItem = {
|
||||
id: '',
|
||||
title: '',
|
||||
status: 0,
|
||||
priority: 2,
|
||||
dueDate: '',
|
||||
remark: ''
|
||||
}
|
||||
this.submitLoading = false
|
||||
},
|
||||
toDelete (index) {
|
||||
let temp = this.dataList[index]
|
||||
let data = {
|
||||
id: temp.id
|
||||
}
|
||||
// 删除按钮转圈,给即时反馈
|
||||
this.$set(this.rowLoading, temp.id, true)
|
||||
remove(data).then(res => {
|
||||
this.refresh()
|
||||
this.getDataList()
|
||||
// 先本地移除,画面立即响应,再静默同步分页数据
|
||||
this.dataList.splice(index, 1)
|
||||
this.pageTotal = Math.max(0, this.pageTotal - 1)
|
||||
// 本页删空了就退回上一页,避免停在空页
|
||||
if (this.dataList.length === 0 && this.pageParam.pageNum > 1) {
|
||||
this.pageParam.pageNum -= 1
|
||||
}
|
||||
this.$set(this.rowLoading, temp.id, false)
|
||||
this.$Message.success('删除成功!')
|
||||
this.getDataList(true)
|
||||
}).catch(() => {
|
||||
this.$set(this.rowLoading, temp.id, false)
|
||||
this.$Message.error('删除失败,请重试')
|
||||
})
|
||||
},
|
||||
updateStatus (row, value) {
|
||||
let status = value === true || value === 1 || value === '1' ? 1 : 0
|
||||
if (row.status === status) {
|
||||
return
|
||||
}
|
||||
let data = {
|
||||
id: row.id,
|
||||
status: status
|
||||
}
|
||||
const oldStatus = row.status
|
||||
// 乐观更新:先改本地,开关立刻响应,不等网络
|
||||
row.status = status
|
||||
this.$set(this.rowLoading, row.id, true)
|
||||
updateStatus(data).then(res => {
|
||||
this.$set(this.rowLoading, row.id, false)
|
||||
this.$Message.success(status === 1 ? '已完成!' : '已标记为未完成!')
|
||||
this.getDataList()
|
||||
// 当前按状态筛选且该行已不匹配条件时,静默刷新让它消失
|
||||
if (this.search.status !== '' && Number(this.search.status) !== status) {
|
||||
this.getDataList(true)
|
||||
}
|
||||
}).catch(() => {
|
||||
this.getDataList()
|
||||
// 失败回滚到原状态
|
||||
this.$set(this.rowLoading, row.id, false)
|
||||
row.status = oldStatus
|
||||
this.$Message.error('状态更新失败,请重试')
|
||||
})
|
||||
},
|
||||
refresh () {
|
||||
// 重置查询条件:回到第一页并重新拉取(原来只清变量不刷列表,点了没变化)
|
||||
this.pageParam = {
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
@@ -323,14 +395,8 @@ export default {
|
||||
status: '',
|
||||
priority: ''
|
||||
}
|
||||
this.formItem = {
|
||||
id: '',
|
||||
title: '',
|
||||
status: 0,
|
||||
priority: 2,
|
||||
dueDate: '',
|
||||
remark: ''
|
||||
}
|
||||
this.resetForm()
|
||||
this.getDataList()
|
||||
},
|
||||
changePage (index) {
|
||||
// 需要显示开始数据的index,(因为数据是从0开始的,页码是从1开始的,需要-1)
|
||||
|
||||
Reference in New Issue
Block a user