Vue中對安卓物理返回鍵的解決方案

本文為純原創(chuàng),如需轉(zhuǎn)載,請注明來源。2019年5月31日 09:13:58

說在前面的話

如果你當(dāng)前使用的庫是JQuery,那請參考我前面的文章<<JavaScript監(jiān)聽安卓物里返回鍵>>
如果是Vue-Cli(不是UMD引入的Vue),請繼續(xù)往下看。

當(dāng)我們向控制物理返回鍵(之后簡稱返回鍵)的時候,無非是想實現(xiàn)兩種功能:

1、 用戶點按返回鍵,不返回到上級頁面,且不進行任何操作,達到禁用返回鍵的目的。
2、用戶點按返回鍵,不返回到上級頁面,但跳轉(zhuǎn)到其它頁面,或者執(zhí)行其它內(nèi)置方法,達到改寫返回鍵的目的。

但由于在Vue項目中,控制頁面跳轉(zhuǎn)使用的是Router,如果直接在public/index.html中添加前文的方法,就會導(dǎo)致物理返回鍵被絕對控制,無法動態(tài)修改的問題。
而如果把前文的方法寫到App.vue中,再在每個頁面按需調(diào)用這個方法,則又會出現(xiàn)事件重復(fù)疊加的bug。
我也苦惱了好一陣,最后找到了個人認(rèn)為比較完美的解決方案。

話不多說。

并未直接給出代碼,而是從實現(xiàn)原理講解。

1. 要實現(xiàn)前文中的pushHistory()方法

不同于傳統(tǒng)JS的是,當(dāng)我們在Vue項目中控制頁面跳轉(zhuǎn)時,為了不破壞Vuex中的數(shù)據(jù),會使用this.$router.push() 來代替 window.location.href

而當(dāng)我們按照前文中提到的方法使用后,發(fā)現(xiàn)vue生成的地址被完整替換掉了。

如圖:


使用前的地址
控制臺執(zhí)行前文方法
使用后的地址

可見,使用前文方法后,由Router生成的hash被破壞掉了,雖然我未發(fā)現(xiàn)這對當(dāng)前頁面有什么影響,但這一定是不可取的。

隨后我修改了這個方法如下:

function pushHistory(){
        var state = {
          title:"title",
          url:window.location.hash};
        window.history.pushState(state,"title",window.location.hash);
      }
      pushHistory()

并把它添加到了index.html里。
因為添加到index.html之后,我的pushHistory()將變成全局可以調(diào)用的方法,因為Vue會將所有的.vue文件渲染到這個index.html中。
我使用 window.location.hash替換掉了#,這樣以保證Router生成的hash不被破壞掉。

注意方法添加的位置

該js代碼添加的位置一定要在head中,否則根據(jù)執(zhí)行順序,如果寫到了body后面,Vue是調(diào)取不到的。

2. 要有一個方法,可以在Vue的任何頁面中調(diào)用,以用于攔截window.onpopstate請求,并且動態(tài)執(zhí)行我們要執(zhí)行的方法。

要實現(xiàn)一個在Vue個頁面中可以調(diào)用的方法很簡單,我們只要寫帶main.js中,再將它掛到原型鏈上即可。
代碼如下:

function gotoURL(callback){
  window.onpopstate = null;
  window.onpopstate = function(){
    callback()
  }
}
Vue.prototype.gotoURL = gotoURL

main.js如圖


image.png

請只看紅框內(nèi)的代碼,不要在意別的。

3、調(diào)用

注意:請不要在App.vue中調(diào)用,因為App.vue只是其它頁面的容器,只會被一次渲染, 我們在配置Router的時候,一般路徑為'/'的頁面會被直接渲染到App.vue中,所以當(dāng)我們要控制初始頁面的返回鍵,需要找到對應(yīng)的vue文件中調(diào)用方法,而不是在App.vue中調(diào)用方法。

調(diào)用一般為 一個頁面一次性調(diào)用,意思就是在頁面渲染的時候,我們就要調(diào)用這個方法。
所以我要(建議)將調(diào)用的方法寫到mounted周期中。如下:

mounted() {
  let that =this;
  pushHistory()  // 必須存在
  that.gotoURL(function () { 
    pushHistory()  // 必須存在
    console.log('666')  // 點擊返回鍵要執(zhí)行的方法
  })
}

為什么要把pushHistory調(diào)用兩次?
我也曾刪掉它們之中的任何一個,但是會出現(xiàn)返回鍵無法正??刂频膯栴},所以先加上,后期如果有更好方法,我會發(fā)上來。

不要濫用這個方法,只在需要的頁面中使用,不需要的頁面中請不要調(diào)用,以防出現(xiàn)問題。

產(chǎn)品設(shè)計建議: PM在設(shè)計產(chǎn)品時,請要考慮移動端的一些問題,盡量避免硬核控制返回鍵的情況出現(xiàn)。

如果讀者有其它需要,可以通過我的簡書首頁簽名下方的微信二維碼添加我好友,請注明來意。

補:

有的朋友問我為什么使用DOM0事件控制popstate而不是DOM2,因為DOM2無法解綁匿名函數(shù),因為我在不同頁面代進來的callback是不一樣的。使用DOM2會出現(xiàn)事件疊加。根據(jù)事件機制,所以使用DOM0,讓每一次的事件都替換上一次的事件。
而在傳統(tǒng)的JS中為什么可以使用DOM2,是因為每一個頁面都切換了運行環(huán)境,所以前一個頁面的DOM2不會和當(dāng)前頁面的DOM2相疊加。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一:什么是閉包?閉包的用處? (1)閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。在本質(zhì)上,閉包就 是將函數(shù)內(nèi)部和函數(shù)外...
    xuguibin閱讀 10,053評論 1 52
  • Vue八個生命周期 beforeCreate【創(chuàng)建前】created【創(chuàng)建后】 beforeMount【載入前】 ...
    艾薩克菊花閱讀 1,444評論 0 12
  • 你知道嗎,古人都是唱歌的高手 現(xiàn)代社會,大家都喜歡聽歌,各種中國好聲音你方唱罷我登場,樂此不疲。其實,...
    學(xué)而忘憂閱讀 5,705評論 0 3
  • 假設(shè)白素貞這個人穿了的白衣服,怎樣才能襯托出她衣服白呢? 那么!只有一個辦法最好用,那就是她首先得奇黑無比,這樣有...
    瑩鴿鴿閱讀 241評論 0 0
  • 下車,麻麻問:3加8等于幾喲?你ban一個來看看??? 小朋友開啟的"裝萌"模式,對麻麻說:"可是我...
    小雍豆子姐姐閱讀 997評論 0 0

友情鏈接更多精彩內(nèi)容