vue中頁面提示是否保存再離開

beforeRouteLeave (to, from, next) {
    //流程頁  人爲點擊保存跳轉頁面   新增
    if(this.processPage && !this.manToSave && this.type=='add'){
      let issave =  confirm('當前頁面沒有保存,是否確定要離開?');
      if(issave){   //確定
        next(true);
      }else{     //取消
        next(false);
      }
      
      //自己寫的彈窗是否保存   不用了
      // this.initPagination(next);
    }else {next(true)}
  }, 

用confirm(‘當前頁面沒有保存,是否確定要離開?’); 而不是用自己寫的el-ddialog或者彈窗

錯誤做法:

一開始的時候我是想着使用vuex結合vue router的beforeEach導航守衛來實現。
用戶在點擊跳轉到另一個頁面的時候會觸發生命週期函數beforeDestroy,如果內容尚未保存,我們就彈出一個提示框,當用戶選擇取消的時候,就將vuex中的introduceState值更新爲true。

</script>
import { mapGetters, mapActions, mapMutations } from "vuex"
export default {
 data() {
  return {
   contentHasSave: false // 記錄用戶是否已經保存內容
  }
 },
 methods: {
  ...mapMutations({
   changeIntroduceState: changeIntroduceState
  })
 },
 beforeDestory: function(){
  if(!contentHasSave){
   // 使用element的提示框
   this.$confirm('您還未保存簡介,確定需要提出嗎?', '提示', {
    confirmButtonText: '確定',
    cancelButtonText: '取消',
    type: 'warning'
   }).then(() => {
    // 選擇確定,正常跳轉
   })
   .catch(() => {
    // 選擇取消
    this.changeIntroduceState(true)
   })
  }
 }
}
</script>

最後在router的beforeEach的導航守衛裏監測from爲當前頁面的所有路由跳轉。當state的introduceState爲true的時候使用next(false)來取消本次路由跳轉

import Vue from "vue";
import VueRouter from "vue-router";
import routeConfig from "./routes";
import {sync} from "vuex-router-sync";
import store from "../store";
//加載路由中間件
Vue.use(VueRouter)
//定義路由
const router = new VueRouter({
 routes: routeConfig,
 //mode: 'history'
})
sync(store, router)
router.beforeEach((to, from, next) => {
 // 簡介也未提交,取消跳轉
 if(from.fullPath === '/adwords/introduce' && store.state.introduceState === 'not-save'){
  next(false)
 }
})
export default router

這種做法其實是行不通的,因爲beforeEach方法的執行其實是在組件beforeDestory的方法之前執行的,也就是說beforeEach執行的時候introduceState的狀態值根本沒有被更新爲true。

vue router的官方文檔,找到了一個絕妙的方法,那就是組件內的導航守衛。

beforeRouteEnter (to, from, next) {
// 在渲染該組件的對應路由被 confirm 前調用
// 不!能!獲取組件實例 this
// 因爲當守衛執行前,組件實例還沒被創建
},
beforeRouteUpdate (to, from, next) {
// 在當前路由改變,但是該組件被複用時調用
// 舉例來說,對於一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候,
// 由於會渲染同樣的 Foo 組件,因此組件實例會被複用。而這個鉤子就會在這個情況下被調用。
// 可以訪問組件實例 this
},
beforeRouteLeave (to, from, next) {
// 導航離開該組件的對應路由時調用
// 可以訪問組件實例 this
}

實現1:(路由變化時有反應)

</script>
export default {
 data() {
  return {
   contentHasSave: false // 記錄用戶是否已經保存內容
  }
 },
  // 組件內導航鉤子,處理未保存退出的情況
 beforeRouteLeave: function(to, from , next){
  if(this.buttonText === '提交'){
   next(false)
   this.$confirm('您還未保存簡介,確定需要提出嗎?', '提示', {
    confirmButtonText: '確定',
    cancelButtonText: '取消',
    type: 'warning'
   }).then(() => {
    // 選擇確定
    next()
   })
  }
 }
}
</script>

實現2:(既能在頁面跳轉也可以在頁面關閉時有反應)

  mounted(){
    window.addEventListener("beforeunload", this.actBeforeUnload,false);  

  },
  //離開新增頁、編輯頁記得解綁,否則其他頁面中也會出現提示的效果
  beforeDestroy() {
    window.removeEventListener("beforeunload",this.actBeforeUnload,false);
  },  
  methods: {
    actBeforeUnload(event){
      if(this.processPage && !this.manToSave && this.type=='add'){
        event.returnValue = "我在這寫點東西...3357"; 
      }else {
        
      }
    },
 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章