El scroll infinito tienen su lugar en la web, pero no encaja en cualquier página web o aplicación. Son especialmente útiles cuando necesitamos cargar grandes cantidades de datos o imágenes cuando el usuario los necesita en lugar de todos a la vez. Las redes sociales como Twitter, Facebook o Instagram los han hecho populares estos últimos años. Integrar tu propio scroll infinito en tu web o aplicación es más fácil de lo que imaginas.
En este artículo vamos a usar la API Usuario Aleatorio (Random User API). Esta API se describe a sí misma como «Igual que Lorem Ipsum, pero para personas». No sólo es genial por su implementación, sino que también es útil para simular perfiles de usuario para proyectos.
Antes de empezar, creamos un nuevo proyecto Vue.js usando la plantilla webpack-simple
de Vue CLI. En este ejemplo usaremos Axios y MomentJS para recuperar datos y formatear fechas, respectivamente.
1 |
$ vue init webpack-simple infinite-scroll-vuejs |
Obteniendo los datos iniciales del usuario
Existen varios paquetes npm para scroll infinito que podemos usar en nuestra aplicación Vue, pero algunos pueden ser excesivamente complejos. Para este artículo, no usaremos ningún plugin o paquete y escribiremos una sencilla función JavaScript que recupera un nuevo grupo de datos cuando llegamos al final de la ventana del navegador.
Antes de empezar a integrar el scroll infinito, recuperamos y asignamos datos iniciales en la carga de la página:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
data () { return { persons: [] } }, methods: { getInitialUsers () { for (var i = 0; i < 5; i++) { axios.get(`https://randomuser.me/api/`) .then(response => { this.persons.push(response.data.results[0]); }); } } }, beforeMount() { this.getInitialUsers(); } |
Vale la pena señalar que no es recomendable hacer cinco llamadas a servicios en la carga. La API Random User sólo devuelve un usuario aleatorio cada vez. Así que para obtener cinco usuarios iniciales, se necesitan cinco llamadas al servicio.
Si mostramos en la consola el array persons
o abrimos las Vue Devtools, deberíamos ver un array de cinco usuarios. Si es así, ¡perfecto! Ahora vamos a iterar sobre estos datos en la template
, darles estilo y continuar:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
<template> <div id="app"> <h1>Random User</h1> <div class="person" v-for="person in persons"> <div class="left"> <img :src="person.picture.large"> </div> <div class="right"> <p>{{ person.name.first }} {{ person.name.last }}</p> <ul> <li> <strong>Birthday:</strong> {{ formatDate(person.dob) }} </li> <li class="text-capitalize"> <strong>Location:</strong> {{ person.location.city }}, {{ person.location.state }} </li> </ul> </div> </div> </div> </template> <script> ... </script> <style lang="scss"> /* Optional Styles */ .person { background: #ccc; border-radius: 2px; width: 20%; margin: 0 auto 15px auto; padding: 15px; img { width: 100%; height: auto; border-radius: 2px; } p:first-child { text-transform: capitalize; font-size: 2rem; font-weight: 900; } .text-capitalize { text-transform: capitalize; } } </style> |
Implementando la lógica del scroll infinito
Ahora, a por lo que hemos venido… ¡el scroll infinito! En los métodos del componente, necesitamos crear una nueva función llamada scroll()
y tenerlo cargado en el método del ciclo de vida mounted()
.
Este método scroll()
debería tener una sencilla condición que calcula el final de la página, evalúa si es verdadero o falos y ejecuta algo. Usaremos las propiedades de los objetos del document
documentElement.scrollTop
y documentElement.offsetHeight
, así como la propiedad innerHeight
para determina si el scroll está en el final:
1 2 3 4 5 6 7 |
window.onscroll = () => { let bottomOfWindow = document.documentElement.scrollTop + window.innerHeight === document.documentElement.offsetHeight; if (bottomOfWindow) { // Do something, anything! } }; |
Dentro de esta condición, añadiremos un método GET
de servicio con Axios para recuperar otro usuario aleatorio de la API Random User.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
methods: { ..., scroll (person) { window.onscroll = () => { let bottomOfWindow = document.documentElement.scrollTop + window.innerHeight === document.documentElement.offsetHeight; if (bottomOfWindow) { axios.get(`https://randomuser.me/api/`) .then(response => { person.push(response.data.results[0]); }); } }; }, }, mounted() { this.scroll(this.person); } |
Esta función realiza una llamada al servicio y añade un nuevo «user» aleatorio al array persons
sólo cuando el usuario realiza un scroll al final de la página. En este punto, deberíamos poder hacer scroll infinitamente y ver un nuevo «user» cada vez.
Conclusión
El scroll infinito suena intimidatorio pero, como hemos demostrado, es bastante sencillo. Con cada scroll al final de la página, recuperamos nuevos datos con Axios y después introducimos esos datos en un array. Para cargar imágenes de forma diferida (lazy load), tan sólo inserta una imagen en el array de datos, itera sobre él en tu template
y vincula <img :src="">
al array.
Nota: puedes encontrar el artículo original en https://alligator.io/vuejs/implementing-infinite-scroll/