Seleccionar página

A la hora de presentar conjuntos de datos en nuestro front-end es habitual paginar las listas de elementos que se muestran al usuario para ofrecer una mejor experiencia. En algunas de estas ocasiones puede ser interesante o imprescindible, por rendimiento de la parte servidora u otras consideraciones, realizar esta paginación de datos en el cliente y no en el servidor. En este artículo veremos como podemos paginar datos en vuejs utilizando el componente de paginación de bootstrap 4 de manera sencilla y sin usar librerías adicionales.

Puedes descargar el código completo de este ejemplo desde GitHub: oddbytes.net/blog

Generando el proyecto Vue

Para empezar de manera rápida con nuestro ejemplo vamos a utilizar la linea de comandos de vue para crear el esqueleto del proyecto y ponernos en marcha de inmediato, como ya hicimos en el artículo de introducción a Vue.js. Si aún no lo has hecho instala globalmente vue-cli:

npm install -g vue-cli

Con vue-cli instalado generar un esqueleto es cuestion de segundos. Vamos a utilizar la plantilla webpack-simple que nos va a generar un proyecto preconfigurado con webpack y servidor web:

vue init webpack-simple paginacion-local

Puedes responder a todas las preguntas con la opción por defecto. Una vez finalizado el asistente solo nos queda instalar con npm los paquetes necesarios:

cd paginacion-local
npm install

Además de los paquetes que vienen por defecto con el esqueleto vamos a instalar bootstrap mediante el paquete de vuejs especifico bootstrap-vue. Para ello, en el carpeta paginacion-local ejecutamos
npm i bootstrap-vue --save
Y ya estamos en dsiposición de arrancar el servidor web:

npm run dev

Si todo está correctamente instalado te cargar en el navegador por defecto la aplicación Vue de referencia

Página de bienvenida generada por vue-cli versión 2.9.x

Mostrando la lista de datos con bootstrap 4

Para comenzar, vamos a incluir en nuestro proyecto las hojas css de bootstrap. En main.js importamos de manera global los siguientes archivos:

import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'

Por otro lado, en el componente App.vue vamos a eliminar por completo el template HTML y la sección de estilos pregeneradas, y en la sección de script vamos a importar y registrar en la aplicación los componentes de bootstrap-vue para generar listas que nos servirán para presentar nuestros elementos:

import bListGroup from "bootstrap-vue/es/components/list-group/list-group";
import bListGroupItem from "bootstrap-vue/es/components/list-group/list-group-item";
export default {
 components: { bListGroup, bListGroupItem }

En la seccion de datos vamos a incluir un array de elementos que contendrá los items a mostrar en la lista:

data() {
  return {
    items: []
  };
}

y aprovecharemos el evento created() del componente vue para inicializar esta lista con datos de prueba:

created() {
  for (let i = 0; i < 28; i++)
    this.items.push({
      id: i + 1,
      nombre: `item ${i + 1}`
  });
}

Por último, vamos a incluir en el template del componente elos elementos necesarios para mostrar nuestra lista de elementos:

<div>
    <b-list-group>
      <b-list-group-item v-for="item in items" v-bind:key="item.id">
       {{item.nombre}}
      </b-list-group-item>
    </b-list-group>
</div>

Tras guardar el fichero, podemos activar el navegador y veremos que este se ha actualizado automaticamente y está ya mostrando nuestra lista presentada con bootstrap:

La lista de elementos sin paginar presentada con bootstrap 4

Añadiendo el paginador

Para navegar a través de las paginas de datos vamos a utilizar el componente de paginación de bootstrap 4 adaptado a vue-js. En primer lugar, debemos importarlo en nuestro script:

 import bPagination from "bootstrap-vue/es/components/pagination/pagination";

Y declararlo en la lista de componentes utilizados:

export default {
  components: { bListGroup, bListGroupItem, bPagination },

De acuerdo con la documentación, debemos hacer binding de las propiedades total-rows para indicar el numero total de elementos y  per-page para indicar el numero de elementos que se mostrarán por página. Además, en la variable que asignemos al binding de v-model se informará la página actual comenzando en 1. Vamos a añadir por tanto dos variables en el conjunto de datos del modelo:

data() {
  return {
    items: [],
    paginaActual: 1,
    itemsPorPagina: 5
  };
}

Y en el html incluimos el componente paginador:

<div>
    <b-list-group>
      <b-list-group-item v-for="item in items" v-bind:key="item.id">
       {{item.nombre}}
      </b-list-group-item>
    </b-list-group>
    <b-pagination align="center" :total-rows="this.items.length " v-model="paginaActual" :per-page="itemsPorPagina" >
    </b-pagination>
</div>

Si comprobamos el navegador, veremos que bajo la lista tenemos el paginador ya dibujado con los enlaces para paginar por los diferentes elementos de 5 en 5. Lógicamente estos enlaces no funcionan aun, pero en el siguiente punto lo uniremos todo:

Paginador dibujado bajo la lista.... aunque aún no pagina

Función de paginación

Nos falta sólo relacionar el paginador  con los elementos que mostramos en nuestra estructura repetitiva de items. Para ello vamos a añadir una función que, dado el array original, nos devuelva únicamente aquellos elementos pertenecientes a la página que está seleccionada en el paginador de bootstrap y que tenga en cuenta el tamaño de página que hemos definido en data:

methods: {
    paginador(items) {
      const indiceInicio = (this.paginaActual - 1) * this.itemsPorPagina;
      const indiceFinal =
        indiceInicio + this.itemsPorPagina > items.length
          ? items.length
          : indiceInicio  + this.itemsPorPagina;
      return items.slice(indiceInicio , indiceFinal );
    }
  },

El método slice nos devuelve una parte de un array sobre uno nuevo sin modificar el array original, lo que es perfecto para nuestra función de paginación.

Ya solo nos queda aplicar esta función a nuestra repetitiva en el código del template:

<b-list-group-item v-for="item in paginador(items)" v-bind:key="item.id">

Y nuestra lista ha quedado paginada localmente:

 

Cada vez que pinchamos uno de los enlaces del paginador este modifica la variable paginaActual, y el sistema reactivo de Vue.js re-evalúa la función paginador(items) que devuelve únicamente los elementos de la lista correspondientes a la pagina seleccionada, por lo que  Vue.js repinta automáticamente la lista en la posición correcta.

Una forma extremadamente rápida y sencilla de paginar datos en el cliente sirviendonos de la potencia de Vue y los componentes de bootstrap 4.

Puedes descargar el código completo de este ejemplo desde GitHub: oddbytes.net/blog
Free WordPress Themes, Free Android Games