1. 程式人生 > >Vue scrollBehavior 滾動行為

Vue scrollBehavior 滾動行為

原文https://www.cnblogs.com/sophie_wang/p/7880261.html

https://blog.csdn.net/wandoumm/article/details/80270865

使用前端路由,當切換到新路由時,想要頁面滾到頂部,或者是保持原先的滾動位置,就像重新載入頁面那樣。 vue-router 能做到,而且更好,它讓你可以自定義路由切換時頁面如何滾動。

注意: 這個功能只在 HTML5 history 模式下可用。

當建立一個 Router 例項,你可以提供一個 scrollBehavior 方法:

複製程式碼

const router = new VueRouter({
  routes: [...],
  scrollBehavior (to, from, savedPosition) {
    // return 期望滾動到哪個的位置
  }
})

複製程式碼

scrollBehavior 方法接收 to 和 from 路由物件。第三個引數 savedPosition 當且僅當 popstate 導航 (通過瀏覽器的 前進/後退 按鈕觸發) 時才可用。

這個方法返回滾動位置的物件資訊,長這樣:

  • { x: number, y: number }
  • { selector: string, offset? : { x: number, y: number }} (offset 只在 2.6.0+ 支援)

如果返回一個 falsy (譯者注:falsy 不是 false

參考這裡)的值,或者是一個空物件,那麼不會發生滾動。

舉例:

scrollBehavior (to, from, savedPosition) {
  return { x: 0, y: 0 }
}

對於所有路由導航,簡單地讓頁面滾動到頂部。

返回 savedPosition,在按下 後退/前進 按鈕時,就會像瀏覽器的原生表現那樣:

複製程式碼

scrollBehavior (to, from, savedPosition) {
  if (savedPosition) {
    return savedPosition
  } else {
    return { x: 0, y: 0 }
  }
}

複製程式碼

 

如果你要模擬『滾動到錨點』的行為:

複製程式碼

scrollBehavior (to, from, savedPosition) {
  if (to.hash) {
    return {
      selector: to.hash
    }
  }
}

複製程式碼

 

我們還可以利用路由元資訊更細顆粒度地控制滾動。檢視完整例子:

複製程式碼

const scrollBehavior = (to, from, savedPosition) => {
  if (savedPosition) {
    // savedPosition is only available for popstate navigations.
    return savedPosition
  } else {
    const position = {}
    // new navigation.
    // scroll to anchor by returning the selector
    if (to.hash) {
      position.selector = to.hash
    }
    // 如果meta中有scrollTop
    if (to.matched.some(m => m.meta.scrollToTop)) {
      // cords will be used if no selector is provided,
      // or if the selector didn't match any element.
      position.x = 0
      position.y = 0
    }
    // if the returned position is falsy or an empty object,
    // will retain current scroll position.
    return position
  }
}

複製程式碼

 

與keepAlive結合,如果keepAlive的話,儲存停留的位置:

複製程式碼

scrollBehavior (to, from, savedPosition) {
     if (savedPosition) {
            return savedPosition
    } else {
        if (from.meta.keepAlive) {
          from.meta.savedPosition = document.body.scrollTop;
        }
        return { x: 0, y: to.meta.savedPosition ||0}
    }
}

 

 

 

 

  在文件頁面(http://localhost:8080/document)拉動滾動條,然後重新整理瀏覽器會發現滾動條依然在原來的位置,這是瀏覽器的預設行為,會記錄瀏覽器滾動條預設位置。

        但是點選瀏覽器“前進/後退”按鈕,會發現當初那個頁面的滾動條從0開始了,沒有記錄上一次滾動條的位置。現在要求點選瀏覽器“前進/後退”按鈕,頁面滾動條要記錄上一次的位置,這時需要設定它的的滾動行為。

        這時候需要在路由配置中設定 scrollBehavior(to,from,savePosition)函式,函式有三個引數。scrollBehavior() 函式在點選瀏覽器的“前進/後退”,或者切換導航的時候觸發。

 
  1. scrollBehavior(to,from,savePosition){ // 在點選瀏覽器的“前進/後退”,或者切換導航的時候觸發。

  2. console.log(to) // to:要進入的目標路由物件,到哪裡去

  3. console.log(from) // from:離開的路由物件,哪裡來

  4. console.log(savePosition) // savePosition:會記錄滾動條的座標,點選前進/後退的時候記錄值{x:?,y:?}

  5. }

QQ截圖20171204104952

        實現滾動行為的程式碼:router/index.js

 
  1. let router = new VueRouter({

  2. mode:'history',//預設是hash模式

  3. linkActiveClass:'menvscode-active',

  4. scrollBehavior(to,from,savePosition){ // 在點選瀏覽器的“前進/後退”,或者切換導航的時候觸發。

  5. console.log(to) // to:要進入的目標路由物件,到哪裡去

  6. console.log(from) // from:離開的路由物件,哪裡來

  7. console.log(savePosition) // savePosition:會記錄滾動條的座標,點選前進/後退的時候記錄值{x:?,y:?}

  8. if(savePosition) {

  9. return savePosition;

  10. }else{

  11. return {x:0,y:0}

  12. }

  13. },

  14. routes:[

  15. {

  16. path:'/',

  17. name:'index',

  18. component:Home,

  19. },

  20. {

  21. path:'/home',

  22. name:'Home',//name代表當前的路由

  23. component:Home,

  24. alias:'/index' //當訪問'/index'的時候,就能匹配到當前的路由了。

  25. },

  26. {

  27. path:'/document',

  28. name:'Document',

  29. components:{ // 多個檢視的時候,預設渲染default的檢視。

  30. default:Document,

  31. slider:Slider,

  32. home:Home

  33. }

  34. }

  35. ]

  36. })

  37.  
  38. export default router

 

        我們還可以設hash來控制滾動行為,定位到某一位置

 
  1. if(to.hash){ //先判斷目標路由有沒有hash值

  2.     return {selector:to.hash}

  3. }

App.vue:在路勁後面新增 hash 值。

 
  1. <template>

  2. <div id="app">

  3. <div class="nav-box">

  4. <ul class="f-cb">

  5. <li>

  6. <router-link to="/" exact tag="div" event="mouseover">home</router-link>

  7. </li>

  8. <li>

  9. <router-link :to="{path:'/document#abc'}" event="mouseover">document</router-link>

  10. </li>

  11. <router-link to="/about" tag="li" event="mouseover">

  12. <i></i>

  13. <span>about</span>

  14. </router-link>

  15. </ul>

  16. </div>

  17. <div class="content f-cb">

  18. <router-view name="slider"></router-view> <!-- 命名檢視 -->

  19. <router-view class="center"></router-view>

  20. </div>

  21. </div>

  22. </template>

@/components/Document.vue

 
  1. <template>

  2. <div>

  3. 我是文件

  4. <p id="abc">定位到這個元素</p>

  5. </div>

  6. </template>

router/index.js

 
  1. let router = new VueRouter({

  2. mode:'history',//預設是hash模式

  3. linkActiveClass:'menvscode-active',

  4. scrollBehavior(to,from,savePosition){ // 在點選瀏覽器的“前進/後退”,或者切換導航的時候觸發。

  5. console.log(to) // to:要進入的目標路由物件,到哪裡去

  6. console.log(from) // from:離開的路由物件,哪裡來

  7. console.log(savePosition) // savePosition:會記錄滾動條的座標,點選前進/後退的時候記錄值{x:?,y:?}

  8. /*if(savePosition) {

  9. return savePosition;

  10. }else{

  11. return {x:0,y:0}

  12. }*/

  13. if(to.hash){ //先判斷目標路由有沒有hash值

  14. return {selector:to.hash}

  15. }

  16. },

  17. routes:[]

  18. })

  19.  
  20. export default router