VUE 離開頁面路由攔截


業務場景

  • 在頁面內容被編輯后,用戶跳轉其他路由,需要提示用戶:當前頁面有改動,確認離開后再進行跳轉,以防編輯數據丟失。

代碼

beforeRouteLeave (to, from, next) {
	 this.targetName = to.name  // 提示框點擊確認后跳轉的 路由
   if (this.checkEdit()) { // 是否對頁面進行了編輯
      this.dialogVisible = true    // 打開離開頁面的提示框
      next(false)
    } else {
      this.dialogVisible = false
      next()
    }
}
  • VUE 提供一個鈎子函數 beforeRouteLeave, 離開當前路由時會先觸發該函數,當然也有beforeRouteEnter,進入路由前先觸發該函數。

  • to: 目標路由的相關信息 對象
  • from:當前路由的相關信息 對象
  • next:實行跳轉的 函數。傳入false,不進行跳轉。

檢測頁面是否編輯

我的思路是在頁面初始化時,設置一個對象保存舊有的值。例如在編輯頁面初始化編輯數據時:

  data () {
		return: {
			formData: {},
     		oldData: {}
      }
  },
  mounted () {
		init() {
     		axios.get(‘/example).then(res => {   // 這里就簡寫了
				Object.assign(this.oldData, res.data) //這里對已有的編輯數據進行保存
   		    this.formData = res.data     // 這里正常回顯
         })
      }
  }

進行存儲后即可保留用戶編輯頁面時的初始狀態。然后離開頁面時進行校驗:

  checkEdit () {
		for (let key in this.oldValObj) {
        if (this.oldValObj[key] != this.formData[key]) {
          return true
        }
      }
      return false
  }


至此,一般情況下的編輯改動即完成了。
但如果你獲得表單數據,是一個對象內還包含對象的數據,
Object.assign() 就會有錯了,它僅支持淺拷貝。我們此時需要使用的是深復制方法了,如下:

 	deepClone (obj) {
   let objClone = Array.isArray(obj) ? [] : {};
   if(obj && typeof obj === ‘object’){
    for(let key in obj){
      // 判斷是不是自有屬性,而不是繼承屬性
      if(obj.hasOwnProperty(key)){
        //判斷ojb子元素是否為對象或數組,如果是,遞歸復制
        if(obj[key]&&typeof obj[key] === ‘object’){
          objClone[key] = this.deepClone(obj[key]);
        }else{
          //如果不是,簡單復制
          objClone[key] = obj[key];
        }
      }
    }
  }
  return objClone;
 }

這種情況下,checkEdit也需要調整。

/*   @param x {Object} 對象1 
 *   @param y {Object} 對象2 
 *   @return {Boolean} true 為相等,false 為不等 
 */
checkEdit(x, y) { // 指向同一內存時 
  if (x === y) {
    return true;
  } else if ((typeof x == "object" && x != null) && (typeof y == "object" && y != null)) {
    if (Object.keys(x).length != Object.keys(y).length) {
      return false;
    }
    for (var prop in x) {
      if (y.hasOwnProperty(prop)) {
        if (!deepEqual(x[prop], y[prop])) {
          return false;
        }
      }
      else {
        return false;
      }
    }
    return true;
  } else {
    return false;
  }
}

總結:

對於一般的表單問題,能確定數據對象中不會包含對象的情形時,數據比較簡單,使用第一種簡易版本會方便調試。數據類型比較復雜的情況,就應該考慮深復制,深對比的思路了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM