在實際應用中,運營人員在編輯數據時不希望因不小心點擊了瀏覽器的回退或刷新按鈕導致花費了很長時間編輯的數據丟失。可以採用以下兩種手段防止運營編輯時丟失數據:
- 在運營人員刷新頁面或回退時,自動保留數據至瀏覽器端本地存儲,在重新進入編輯頁面時再將數據從本地存儲中加載到編輯界面。
- 第二種方法是在運營人員刷新或回退時,強提示運營人員有修改的數據尚未保存,詢問是否繼續。
無認採用哪一種方式,在技術實現上,我們需要首先能夠監聽到用戶執行回退或刷新頁面的動作。
實際上,當用戶執行頁面刷新時,會觸發window
對象上的onBeforeUnload
事件。所以,我們需要在頁面加載時開始監聽此事件。在Vue.js應用中,我們可以在Vue.js的mounted
生命週期事件函數中開始監聽。
mounted() {
window.onbeforeunload = e => {
if (!this.modified) {
return;
}
// 通知瀏覽器不要執行與事件關聯的默認動作
e.preventDefault();
// Chrome 需要 returnValue 被設置成空字符串
e.returnValue = '';
};
},
有了以上的代碼,只要我們在修改了數據以後,將modified
的值改爲true,則可以在刷新整個頁面時彈出如下提示:
當用戶點擊上述對話框的[取消]按鈕後,會取消刷新動作,當用戶選擇[重新加載]後,瀏覽器會強制進行頁面的刷新。
由於在Vue.js應用中,通常是一個頁面的應用,所有的子頁面享用一個window對象,所以,如果在一個Vue.js頁面組件中增加了對onBeforUnload事件的監聽,則可能會影響其它頁面組件的相關行爲,而在其他頁面(如,僅瀏覽數據的頁面)是不希望進行相關的提示的,所以,我們需要在Vue.js組件卸載的時候取消對onBeforeUnload事件的監聽。
destroyed() {
// 取消對事件的監聽
window.onbeforeunload = null;
},
用戶除了通過瀏覽器刷新操作退出外,還有兩種可能的退出途徑:
- 點擊瀏覽器的前進或回退操作按鈕
- 點擊單頁面中的前端路由鏈接
對於以上兩種退出途徑,onBeforeLoad事件通常是攔截不到相應的事件的,因爲這兩種操作一般是前端路由的行爲。
既然是前端路由的行爲,我們就需要在前端路由事件上下功夫。可喜的是,前端路由vue-router爲我們提供了導航守衛
的能力。關於vue-router導航守衛的相關知識,大家可以參考:vue-router前端路由導航守衛。
前端路由導航守衛分爲全局守衛、獨享守衛、組件內守衛等。這裏我們使用的是組件內守衛。
組件內守衛有以下三種
- beforeRouteEnter 組件第一次被渲染時調用
- beforeRouteUpdate 路由改變但組件被複用時調用
- beforeRouteLeave 導航離開組件時調用
顯而易見,我們需要監聽並處理beforeRouteLeave
事件。
beforeRouteLeave(to, from, next) {
if (!this.modified) {
next();
return;
}
this.$confirm('當前頁面數據未保存,確定要離開?', '提示', { type: 'warning' })
.then(() => {
next();
})
.catch(() => {
next(false);
});
},
有了以上的代碼,當我們在進行路由切換時(點擊瀏覽器回退按鈕或點擊頁面中的其它路由鏈接)就會提示如下的對話框:
當用戶選擇取消時,回到原界面,當用戶點擊確定按鈕後,頁面強制刷新。
>以上是本人在實際項目應用中遇到的問題及我們採取的解決方案,如果您有更好的方法,或者有更好的建議,歡迎不吝賜教。