Vue實(shí)現(xiàn)頁面返回停留原位置的多種方案
一.問題背景
在開發(fā) H5 項(xiàng)目的時(shí)候,本來沒有考慮到頁面返回停留到原位置這個(gè)需求,正常的進(jìn)行 Vue 路由的跳轉(zhuǎn),直接進(jìn)行 Vue 路由的跳轉(zhuǎn),正常情況如果不使用keep-alive進(jìn)行組件緩存的情況下,跳轉(zhuǎn)到一個(gè)頁面后返回頁面是要正常走 Vue 的聲明周期進(jìn)行刷新的,但是在 H5 端用戶可能更希望在跳轉(zhuǎn)后返回還是停留在原來的位置,所以就要對(duì)之前的代碼進(jìn)行修改來滿足這個(gè)需求,其實(shí)在安卓或者 IOS 殼子中打開一個(gè)webview原來的這個(gè)webview會(huì)被正常的緩存到,還會(huì)停留在之前的位置,之前的操作也會(huì)被緩存到,可以理解為我們新打開了一個(gè)瀏覽器的標(biāo)簽頁,新的標(biāo)簽頁對(duì)原來的標(biāo)簽頁面不會(huì)造成任何的影響,雖然本質(zhì)上還是有些差別,所以實(shí)現(xiàn)上述的需求的方案有很多,所以就總結(jié)一下各種方案的優(yōu)缺點(diǎn),以及適用情況。
二.Vuex 實(shí)現(xiàn)方案
使用 Vuex 來實(shí)現(xiàn)返回停留在原來的位置基本的思路就是當(dāng)離開這個(gè)頁面的時(shí)候通過scrollTop來記錄下具體的位置然后通過 Vuex 進(jìn)行存儲(chǔ),然后返回的時(shí)候進(jìn)入頁面之前就從 Vuex 中取出來,等到頁面加載完畢就滾動(dòng)到具體位置。
- 優(yōu)點(diǎn):不需要緩存 Vue 頁面,不會(huì)對(duì)頁面的的正常生命周期造成影響,只需要新增邏輯,不需要修改原來的代碼,修改的時(shí)候不容易出現(xiàn) bug。
- 缺點(diǎn):返回之后原來的頁面會(huì)重新請(qǐng)求,雖然可也停留在原來的位置,但是當(dāng)原頁面加載完畢位置還是會(huì)因?yàn)榻M件的變化而微小變動(dòng),頁面會(huì)出現(xiàn)閃動(dòng),原來的操作無法記錄,重新請(qǐng)求容易給服務(wù)器造成壓力。
這個(gè)方案其實(shí)實(shí)現(xiàn)的僅僅就是滾動(dòng)到原來的位置,并且由于 H5 有的要使用客戶端跳轉(zhuǎn)可能會(huì)造成失效的情況,如果是最初開發(fā)階段不建議使用此方案,本方案適用于在原來沒有這個(gè)效果的頁面上增加這個(gè)效果的時(shí)候使用。
beforeRouteLeave(to, from, next) {
let position = document.querySelector("#app").scrollTop; //記錄離開頁面時(shí)的位置
if (position == null) position = 0;
this.$store.commit("pageLocation/setPagePostion", position); //離開路由時(shí)把位置存起來,
next();
},
computed: {
...mapState({
pagePostionNum: (state) => state.pageLocation.pagePostion,
}),
},
mounted() {
this.isTabRoute();
},
methods: {
isTabRoute() {
if (this.$route.path === "/ETFZone") {
document.querySelector("#app").scrollTop = this.pagePostionNum;
}
},
}
提示:H5 中頁面沒有可以刷新的按鈕所以在 Vuex 的數(shù)據(jù)不需要擔(dān)心刷新會(huì)丟失,但是在 PC 需要考慮。
三.keep-alive 方案
keep-alive 的方案和 Vuex 的方案思路基本一致,將具體頁面緩存,通過keepAlive在路由 meta 中的配置來選擇合適的時(shí)間釋放緩存,在頁面離開的時(shí)候通過scrollTop記錄位置,然后當(dāng)返回這個(gè)頁面的時(shí)候在activated這個(gè)生命周期進(jìn)行激活滾動(dòng)到原來的位置。
- 優(yōu)點(diǎn):可以緩存頁面原來的操作,用戶體驗(yàn)感更好,實(shí)現(xiàn)思路更加符合主流實(shí)現(xiàn)方案。
- 缺點(diǎn):面對(duì)改造的業(yè)務(wù)會(huì)對(duì)原來代碼進(jìn)行更改,并且因?yàn)榧恿司彺妫芏嗖僮餍枰せ?,容易出現(xiàn) bug
這個(gè)方案適合在項(xiàng)目或者模塊開發(fā)的初期考慮進(jìn)取當(dāng)作主要實(shí)現(xiàn)方案,對(duì)于維護(hù)的代碼可能會(huì)出現(xiàn) bug,不容易修改。
beforeRouteLeave(to, from, next) {
this.rememberScroll = document.querySelector("#app").scrollTop;
next();
},
// 緩存組件激活時(shí)調(diào)用
activated() {
document.querySelector("#app").scrollTop = this.rememberScroll;
console.log(document.querySelector("#app").scrollTop, "距離頂部的距離");
},
四.v-show 方案
v-show方案相對(duì)于前兩種是最簡(jiǎn)單的,并且可以一個(gè)頁面全部梭哈,自己對(duì)代碼請(qǐng)求更新時(shí)機(jī)也比較容易把控,不需要考慮位置的記錄,激活等等問題。
- 優(yōu)點(diǎn):簡(jiǎn)單易懂,代碼可控度較高,不容易出現(xiàn) bug 等緩存造成的問題。
- 缺點(diǎn):路由不可用,需要自己編寫路由棧,頁面過多會(huì)造成代碼冗余,難以維護(hù)。
/**
* @class VshowRouter 模擬路由
* @from 當(dāng)前頁面路由
* @to 要跳轉(zhuǎn)的頁面路由
* @method addRouter 添加要跳轉(zhuǎn)的路由
* @method navigatorRoute 返回最近的路由
* @method deleteRoute 刪除棧頂元素-最近跳轉(zhuǎn)的路由
* @method clearRoute 清空整個(gè)路由棧
* @method customRoute 自定義路由跳轉(zhuǎn)-返回將要跳轉(zhuǎn)的路徑
*/
class VshowRouter {
constructor() {
this.route = []
}
addRouter(from) {
this.route.push(from)
}
navigatorRoute() {
if (this.route.length >= 1) {
const lastRoute = this.route[this.route.length - 1]
if (lastRoute >= 1) {
this.deleteRoute()
return lastRoute
}
}
}
deleteRoute() {
if (this.route.length > 0) {
this.route.pop()
}
}
clearRoute() {
if (this.route.length > 0) {
this.route.splice(0)
}
}
customRoute(from, to) {
this.addRouter(from)
return to
}
}
export const vShowRouter = new VshowRouter()
在頁面中我們就可以使用v-show來進(jìn)行控制展示,每展示的頁面要進(jìn)入上述的棧中來控制路由。
<main>
<SearchContent
v-show="searchStep === 'one'"
@goSearchUser="navUserResource"
@createOther="createOther"
:obj="obj"
@chioceResultTag="chioceResultTag"
/>
<SearchResult
:searchStatus="searchStatus"
@navUser="navJump"
:ArrayData="ArrayData"
v-show="searchStep === 'two'"
/>
<UserBasicInformation
@goNext="goNextStepTwo"
:userBasic="userBasic"
:userExperience="userExperience"
v-show="searchStep === 'three'"
/>
</main>
雖然v-show寫起來比較簡(jiǎn)單,但是如果需要支持路由的情況就會(huì)變的相對(duì)復(fù)雜起來,需要自己模擬路由來實(shí)現(xiàn)路由棧來解決這個(gè)問題,如果頁面很簡(jiǎn)單或者只需要在頁面中的某個(gè)組件相互切換比較適合選擇使用。
五.客戶端跳轉(zhuǎn)方案
在 H5 可以通過客戶端跳轉(zhuǎn)新開webview來解決上述的問題,并且不會(huì)造成其他的問題,我們來看下這種方案的優(yōu)缺點(diǎn)。
- 優(yōu)點(diǎn):直接跳轉(zhuǎn)新的
webview不會(huì)出現(xiàn)上述問題,僅需要更改跳轉(zhuǎn)為客戶端的跳轉(zhuǎn)方法。 - 缺點(diǎn):參數(shù)傳遞,參數(shù)接收不容易監(jiān)控,打開太多
webview容易造成性能問題。
如果需要跳轉(zhuǎn)的頁面有一頁或者一個(gè) Vue 文件可以搞定,其實(shí)使用這種方法能夠很大程度上解決這個(gè)問題,并且可以和v-show的方案一起使用。
toUrlBan(str) {
T.fn.action10061({
url: str,
tzthiddentitle: "0",
TITLETYPE: "1",
});
},
六.問題總結(jié)
這篇文章到這里就結(jié)束了 ??,其實(shí)面對(duì)這類問題應(yīng)該盡量在開發(fā)前將相應(yīng)的前端業(yè)務(wù)和用戶體驗(yàn)考慮周全,因?yàn)槿绻捌诳紤]不到,后期新增這些功能的時(shí)候會(huì)非常的麻煩,并且可能會(huì)造成未知的 bug,除了上述的方案其實(shí)還有其他的方法但是基本原理都差不多,基本都是緩存和組件隱藏顯示,在使用的使用應(yīng)當(dāng)根據(jù)自己的實(shí)際業(yè)務(wù)選擇適合自己的方案。
以上就是Vue實(shí)現(xiàn)頁面返回停留原位置的多種方案的詳細(xì)內(nèi)容,更多關(guān)于Vue頁面返回停留原位置的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
element ui loading加載開啟與關(guān)閉方式
這篇文章主要介紹了element ui loading加載開啟與關(guān)閉方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
Vue3與pywebview實(shí)現(xiàn)獲取本地文件夾的絕對(duì)路徑
這篇文章主要為大家詳細(xì)介紹了Vue3如何結(jié)合pywebview實(shí)現(xiàn)獲取本地文件夾的絕對(duì)路徑,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下2024-11-11
postcss-pxtorem設(shè)置不轉(zhuǎn)換UI框架的CSS單位問題
這篇文章主要介紹了postcss-pxtorem設(shè)置不轉(zhuǎn)換UI框架的CSS單位問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07
Vue+Echarts實(shí)現(xiàn)繪制多設(shè)備狀態(tài)甘特圖
這篇文章主要為大家詳細(xì)介紹了Vue如何結(jié)合Echarts實(shí)現(xiàn)繪制多設(shè)備狀態(tài)甘特圖,文中的示例代碼講解詳細(xì),有需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03
vite.config.ts如何加載.env環(huán)境變量
這篇文章主要介紹了vite.config.ts加載.env環(huán)境變量方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
詳解Vuejs2.0 如何利用proxyTable實(shí)現(xiàn)跨域請(qǐng)求
本篇文章主要介紹了Vuejs2.0 如何利用proxyTable實(shí)現(xiàn)跨域請(qǐng)求,具有一定的參考價(jià)值,有興趣的可以了解一下2017-08-08
基于Vue設(shè)計(jì)實(shí)現(xiàn)一個(gè)彈幕組件
這篇文章主要給大家分享一個(gè)開發(fā)中常見的需求,接下來將為大家詳細(xì)介紹彈幕的實(shí)現(xiàn)以及設(shè)計(jì)思路一步一步描述出來,希望大家能夠喜歡2023-06-06

