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