我们经常会遇到界面信息填写一半不小心滑动键盘后页面跳转数据消失的例子,最开始在使用gitLab 提交任务时会遇到此问题,感觉一点不友好,不过gitLab现在编辑数据未保存返回时有弹框提示。那如果在项目中也遇到此问题该如何实现呢?
点击返回/放弃按钮出现的弹框
实现思路
-
界面数据如果都是对象可以使用
watch
监听实现 (纯对象)data() { return { updateCount: 0, formItem:{} //界面展示的数据 } }, watch:{ //监听formItem对象,界面数据有变化时updateCount增加 formItem: { handler(newVal) { this.updateCount++ }, deep: true } }, methods:{ goBack(){ //如果updateCount>0 说明界面数据有改变出现弹框提示是否确认返回,否则直接返回上一页 if (this.updateCount > 0) { this._MessageBox("确定返回?", "返回后,修改的数据将不保存", "").then(() => { //_MessageBox是封装的弹框方法(自己根据需求定义即可) this.$router.go(-1); }).catch(() => { }); } else { this.$router.go(-1); } } }
但是如果界面有表格数据(数组)继续使用上面的监听方法并不可行。
-
数据
拷贝对比
(对象里面嵌套数组)刚进页面拷贝数据,之后与编辑后的数据做对比。
import deepClone from "./deepClone.js"; data() { return { editFlag:false, formItem:{}, //界面展示的数据 formItemOld:{} } }, methods:{ getDetail(){ //刚进页面获取详情数据 let res = await this.$http.qualificationRequest.getDetail(this.$route.query.id); //调接口 if (res.code === '200') { this.formItem = res.data; this.formItemOld = deepClone(res.data); //克隆数据(封装的方法) } else { this.$message.error(res.data); } }, //返回按钮 goBack(){ for (const key in this.formItemOld) { //JSON.stringify转换数据后比对 if (JSON.stringify(this.formItem[key]) !== JSON.stringify(this.formItemOld[key])) { this.editFlag = true; } } //如果 editFlag:true 说明界面数据有改变,出现弹框提示是否确认返回,否则直接返回上一页 if (this.editFlag) { this._MessageBox("确定返回?", "返回后,修改的数据将不保存", "").then(() => { //_MessageBox是封装的弹框方法(自己根据需求定义即可) this.$router.go(-1); }).catch(() => { }); } else { this.$router.go(-1); } } }
封装的克隆方法
deepClone.js:
function deepClone (obj) {
// 对常见的“非”值,直接返回原来值
if([null, undefined, NaN, false].includes(obj)) return obj;
if(typeof obj !== "object" && typeof obj !== 'function') {
//原始类型直接返回
return obj;
}
var o = isArray(obj) ? [] : {};
for(let i in obj) {
if(obj.hasOwnProperty(i)){
o[i] = typeof obj[i] === "object" ? deepClone(obj[i]) : obj[i];
}
}
return o;
}
function isArray(arr)(){
return Object.prototype.toString.call(arr) === '[object Array]';
}
export default deepClone;