情況
- 頂部返回,在header.vue公用組件中使用
this.$router.go(-1)
- 安卓:點擊返回按鈕:登錄頁,項目選擇頁,首頁等幾個一級頁面要求提示用戶是否退出app;確定,退出;取消:不做操作;
- iOS:還未處理
預期
在一個公用js文件中使用編寫一個函數(phoneOperate(isTopPage)
):讓app在點擊手機返回按鈕的時候默認返回上級,在一級頁面單獨處理讓用戶在點擊的時候做提示.
phoneOperate(isTopPage){
let that = this
isTopPage = isTopPage || false;
if(isTopPage){
that.$confirm('是否要退出app','操作提示')
.then((){ plus.runtime.quit()})
.catch((){return;})
} else {
that.$router.go(-1);
}
}
情況1
- 在
app.vue
組件中調用phoneOperate(isTopPage)
實現所有頁面點擊手機返回鍵,返回上級頁面
結果
app.vue組件在最開始初始化一次;之后加載一級頁面的.vue組件時,是不會再次渲染的,因此所有的頁面(包括一級頁面)都只是會執行首次進入app時的條件.而在一級頁面改寫過返回按鈕后進入非一級頁面,因為沒有對所有非一級頁面改寫返回按鈕,所有頁面都將繼續執行一級頁面的邏輯.
情況2
因為app.vue中調用所有所有其他.vue組件,即其他所有組件都是app.vue組件的子組件.能不能利用父子組件傳值改變全局變量(isTopPage)的值
結果2
大概是入口組件的特殊性 app.vue組件中的
情況3
不知道具體有什么簡單的辦法,那就使用體力勞動了:每一頁面都去執行一個函數,讓他們都去覆寫一遍點擊返回按鈕的函數.淚奔┭┮﹏┭┮,想哭的心,像玻璃碎片...............
phone.js
import {
Indicator,
Toast
} from 'mint-ui'
let o = {
stopBack() {
let that = this;
plus.key.removeEventListener('backbutton',function(){});
plus.key.addEventListener("backbutton", function() {
Indicator.close();
that.$confirm('確定要退出程序嗎?','操作提醒',{
confirmButtonText: '退出',
cancelButtonText: '取消'
}).then(() => {
plus.runtime.quit()
}).catch(() => {
return
})
}, false)
},
back(beforeBack) { // 點擊手機`返回`按鈕,非主頁面返回上級;如果有返回前處理執行,如果前處理沒有返回,或返回!true不再執行返回事件
plus.key.removeEventListener('backbutton',function(){});
plus.key.addEventListener("backbutton", function() {
let cross = false;
Indicator.close();
if(beforeBack){
cross = beforeBack()
}
if(cross){
history.go(-1);
}
}, false)
}
}
window.phone = o;
export default o;
一級頁面執行如下代碼
import phone './phone.js'
...
created: function() {
let that = this;
document.addEventListener('plusready',function(){
phone.stopBack.call(that);
})
}
非一級頁面執行如下代碼
import phone './phone.js'
...
created: function() {
document.addEventListener('plusready',function(){
phone.back;
})
}
結果3(只會執行一次)
在登錄頁面加載完成后,會執行phone.stopBack.call(that)
,但是在切換到別的頁面后,不會再執行非一級頁面組件中的
created: function() {
document.addEventListener('plusready',function(){
phone.back;
})
}
最終狀態
在將phone.js
改寫,將其中的phone
對象添加到Vue對象的原型上,能夠在所有組件中直接調用phone
對象.
phone.js
import Vue from 'vue'
import {
Indicator,
Toast
} from 'mint-ui'
let o = {
stopBack() {
let that = this;
plus.key.removeEventListener('backbutton',function(){});
plus.key.addEventListener("backbutton", function() {
Indicator.close();
that.$confirm('確定要退出程序嗎?','操作提醒',{
confirmButtonText: '退出',
cancelButtonText: '取消'
}).then(() => {
plus.runtime.quit()
}).catch(() => {
return
})
}, false)
},
back(beforeBack) { // 點擊手機`返回`按鈕,非主頁面返回上級;如果有返回前處理執行,如果前處理沒有返回,或返回!true不再執行返回事件
plus.key.removeEventListener('backbutton',function(){});
plus.key.addEventListener("backbutton", function() {
let cross = false;
Indicator.close();
if(beforeBack){
cross = beforeBack()
if(cross){
history.go(-1);
}
}else{
history.go(-1);
}
}, false)
}
}
window.phone = o; // 掛載到window上
Vue.prototype.phone = o;
export default o;
組件中的處理
在入口組件(非app.vue,本例為login.vue)中.
created: function() {
let that = this;
document.addEventListener('plusready',function(){ // 這里必須得鑒定plusready事件,否則會提示plus沒有定義
phone.stopBack.call(that); // 點擊手機`返回`按鈕
})
}
在首頁/我的/聊天這幾個和二級頁面有關聯的一級頁面中的處理
/*created*/mounted: function() { // 這里必須用mounted,是因為頁面1關閉和頁面2打開的節點是:頁面2先created,頁面1再destroyed,接着頁面1mounted
let that = this;
// document.addEventListener('plusready',function(){
// phone.stopBack.call(that);
// })
// 上面注釋掉的代碼會因為無法監聽到`plusready`事件而不能夠重寫手機的`backButton`事件
phone.stopBack.call(that); // 點擊手機`返回`按鈕
},
destroyed(){
phone.back()
}
注意:本例中login->項目選擇->首頁的模式下,login和項目選擇組件中是不需要在組件摧毀的時候覆寫backButton
的,因為首頁也是一級頁面需要提示.但是和首頁平行的幾個頁面(聊天/我的)需要再組件摧毀的時候單獨處理成默認的返回上級,這是因為它們往往會直接進入二級頁面,而在二級頁面中需要點擊返回按鈕返回上級的操作.