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.

Build faster with AI
New Masterclass to help you leverage AI in your Vue workflow.
Get Early Access