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 {
}
},
}