Skip to content

Comportamiento del scroll

Cuando usamos enrutamiento del lado del cliente, podemos querer desplazarnos al principio cuando navegamos a una nueva ruta, o preservar la posición de desplazamiento de las entradas del historial tal y como hace la recarga real de la página. Vue Router te permite lograr esto y aún mejor, te permite personalizar completamente el comportamiento de desplazamiento en la navegación de la ruta.

Nota: esta característica sólo funciona si el navegador soporta history.pushState..

Al crear la instancia del router, puedes proporcionar la función scrollBehavior:

js
const router = createRouter({
  history: createWebHashHistory(),
  routes: [...],
  scrollBehavior (to, from, savedPosition) {
    // retorna la posición deseada
  }
})

La función scrollBehavior recibe los objetos de ruta to y from, como Protectores de Navegación. El tercer argumento, savedPosition, sólo está disponible si se trata de una navegación popstate (activada por los botones atrás/adelante del navegador).

La función puede retornar un objeto de posición ScrollToOptions:

js
const router = createRouter({
  scrollBehavior(to, from, savedPosition) {
    // desplazarse siempre hacia arriba
    return { top: 0 }
  },
})

También puedes pasar un selector CSS o un elemento del DOM a través de el. En ese caso, top y left serán tratados como posiciones relativas a ese elemento.

js
const router = createRouter({
  scrollBehavior(to, from, savedPosition) {
    // desplazarse siempre 10px por encima del elemento #main
    return {
      // también podría ser
      // el: document.getElementById('main'),
      el: '#main',
      // 10px por encima del  elemento
      top: 10,
    }
  },
})

Si se devuelve un valor falso o un objeto vacío, no se producirá ningún desplazamiento.

Devolver la savedPosition resultará en un comportamiento similar al nativo cuando se navegue con los botones atrás/adelante:

js
const router = createRouter({
  scrollBehavior(to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition
    } else {
      return { top: 0 }
    }
  },
})

Si desea simular el comportamiento "scroll hasta el ancla":

js
const router = createRouter({
  scrollBehavior(to, from, savedPosition) {
    if (to.hash) {
      return {
        el: to.hash,
      }
    }
  },
})

Si tu navegador soporta comportamiento del scroll, puedes hacerlo más suave:

js
const router = createRouter({
  scrollBehavior(to, from, savedPosition) {
    if (to.hash) {
      return {
        el: to.hash,
        behavior: 'smooth',
      }
    }
  },
})

Retardando el scroll

A veces necesitamos esperar un poco antes de desplazarnos en la página. Por ejemplo, cuando se trata de transiciones, queremos esperar a que la transición termine antes de desplazarnos. Para ello podemos devolver una Promise que devuelva el descriptor de posición deseado. Aquí hay un ejemplo donde esperamos 500ms antes de desplazarnos:

js
const router = createRouter({
  scrollBehavior(to, from, savedPosition) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve({ left: 0, top: 0 })
      }, 500)
    })
  },
})

Es posible conectar esto con eventos de un componente de transición a nivel de página para hacer que el comportamiento del scroll funcione bien con las transiciones de tu página, pero debido a la posible variación y complejidad en los casos de uso, simplemente proporcionamos esta función primitiva para permitir implementaciones específicas del usuario.

Publicado bajo licencia MIT.