vue+vuex 回退定位到初始位置


先放出兩張圖(沒錯,你還在9012,做為一名資深設計師我唯一的技能點就是留白),簡單說明下問題
未做回退定位(從落地頁回退,每次都回到A位置)想死啊有木有,每次都需要手動重新定位來選擇,你大哥看到你做個這肯定想扣死你:

添加回退定位后(從落地頁回退,定位到點擊位置)哈,好用到爆 有木有~:


按照WBD國際通用慣例(我編的),先對這個demo中用到的文件做一個索引,方便對整個回退功能有個宏觀的視角,更容易理解整個流程是怎么走通的,做到心中有術。
這個回退定位demo共涉及到5個文件,分別如下:
BackToA.vue 組件A,也就是需要回退定位的組件,也就是開篇的車禍現場
Alphabet.vue 組件B,跳轉落地頁,不重要
index.js 在這個文件中進行,配置路由,添加meta屬性(keepAlive),很重要
App.vue 模板文件,引入組件(router-view),依據路由是否添加meta屬性判斷是否啟用keep-alive進行組件緩存
main.js 入口文件,引入vuex,在state定義_scrollTop來記錄scrollTop值,和改變state值的actions方法來提交mutation更新狀態
demo目錄結構如下圖:

看到這,有沒有感覺很宏觀。是不是心中有了術,對這個小demo產生了王的蔑視。少年請留步,話說,有術無道,止於術,再給我兩分鍾,讓我把記憶結成冰,說“道”。
道:首先對組件BackToA啟用keep-alive緩存,當組件BackToA上下滾動時記錄當前頁的scrollTop值,並把這個值存儲在vuex的state中。當從落地組件B回退到組件BackToA時,緩存生效,組件BackToA不再重新渲染。此時拿到vuex state中存儲的scrollTop值,賦值給BackToA組件,實現定位到跳轉前的位置。
其實我是一名程序員,ok,下面開始我們喜聞樂見的編程環節。
1.引入vuex存儲scrollTop值
因為vuex是整個流程的核心,先把這部分放到第一個梳理清楚方便后面的流程持續進行(我們都受過被打斷的傷痛在我這決不允許)(打斷的都是工作,沒有其它的亂七八糟的什么東西不要亂聯想)。
打開入口文件main.js(一般都是這個文件),在這個文件中定義一個store常量、存儲一個_scrollTop來存儲組件上下滾動時頁面的scrollTop值、引入vuex,並啟用

源碼如下

import Vuex from 'vuex'
Vue.use(Vuex)

 

const store = new Vuex.Store({
state: {
_scrollTop: 0 // 存儲組件的scrollTop值
},
mutations: {
updatePosition (state, payload) {
state._scrollTop = payload.top // 更改scrollTop值
}
},
actions: {
updatePosition ({commit}, top) { 
commit({type: 'updatePosition', top: top}) // 提交mutation 更改狀態
}
}
})

2.創建組件BackToA

①引入vuex中的mapState和mapActions

import { mapState, mapActions } from 'vuex'

②在computed計算屬性中定義demoTop變量,並讀取state中的_scrollTop值給其賦值

computed: {
...mapState({
demoTop: state => state._scrollTop, // 獲取 state 中存儲的top值
}),
},

③創建監聽頁面滾動方法,實時監聽當前頁面的scrollTop值,這個監聽放在mounted鈎子中觸發的原因是:此時頁面dom已經渲染完畢

mounted: function () {
console.log("==mounted===");
document.querySelector('.hello').addEventListener('scroll', this.handleScroll, false);
},

  

methods:{
handleScroll(){
this.box = document.querySelector('.hello')
}, 
},

④實時獲取當前頁面scrollTop值,提交mutation更新狀態

methods:{
handleScroll(){
this.box = document.querySelector('.hello')
this.updatePosition(this.box.scrollTop)
}, 
...mapActions([
'updatePosition'
]), 
},

⑤緩存數據讀取,更新scrollTop值,實現定位

activated () {
document.querySelector('.hello').scrollTop = this.demoTop // 更新緩存組件的scrollTop值
},

⑥頁面布局

注:我們在這個例子中得到的scrollTop值,是屬於class='hello'的,所以在組件中BackToA必須只有class='hello'的div支持 overflow:scroll才行

<template>
<div class="hello">
<ul>
<li v-for="(item,index) in 26" :key="index">
<router-link :to="{ name: 'Alphabet', params: { letter: String.fromCharCode(64+item) }}">{{String.fromCharCode(64+item)}}</router-link> 
</li> 
</ul>
</div>
</template>
<style scoped>
.hello{
height:600px;
overflow:scroll;
}
.hello>ul{
height:auto;
overflow:hidden;
background:#eee;
}
.hello>ul>li{
height:60px;
line-height:60px;
width:100%;
float:left;
margin:0;
border-bottom:1px dashed #ccc;
}
</style>

3.創建落地組件Alphabet

<template>
<div class="hello">
<div><button @click="goback">goback</button></div>
<ul>
<li>
this is <strong>{{ $route.params.letter }}</strong>
</li> 
</ul>
</div>
</template>

4.配置組件緩存

①在router/index.js文件中給/backto/backtoa路由添加meta緩存屬性:meta: { keepAlive: true }

{
path: '/backto/backtoa',
name: 'BackToA',
component: BackToA,
meta: { keepAlive: true }
}	

②在App.vue模板文件中根據是否添加meta屬性判斷是否開啟緩存機制:

<template>
<div id="app">
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
</div>
</template>

**本篇完再見**

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM