laravel-clicko-informatica-paginacion-vue

Si utilizas Vue con Laravel y te gustaría aprovechar la paginación que implementa Laravel en tu proyecto, hoy en el Blog de CLiCKO verás una posible solución. 

Preparación

Empezaremos editando el fichero de factories que viene por defecto y añadiremos la siguiente función:

$factory->define(App\Contacto::class, function (Faker $faker) {
    return [
        'nombre' => $faker->name
    ];
});

Esta función nos servirá para posteriormente añadir datos de prueba para nuestra tabla.

Ahora crearemos el modelo y la migracion utilizando el comando:

php artisan make:model Contacto -m

Abrimos el fichero Contacto.php que nos a creado en la carpeta App y lo dejamos de la siguiente forma:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Contacto extends Model
{
    protected $fillable = [
        'nombre'
    ];
}

También tendremos que editar la migración para añadir la columna que contendrán los datos de prueba, para eso vamos a la carpeta migrations y editamos el fichero que tendrá de nombre create_contactos_table, modificaremos la función up para dejarla así:

public function up()
{
        Schema::create('contactos', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('nombre');
            $table->timestamps();
        });
}

Después creamos el Seeder con el siguiente comando:

php artisan make:seeder ContactoSeeder

Una vez tengamos el seeder, en la función run() tendremos que añadir una llamada a la función factory que habíamos creado anteriormente

public function run()
{
    factory(App\Contacto::class, 50)->create();
}

Finalmente en el fichero DatabaseSeeder añadiremos la llamada para que ejecute nuestro seeder, para eso editamos la función up()

public function run()
{
        $this->call(ContactoSeeder::class);
}

Ahora ya podemos ejecutar la migración con los seeders mediante Laravel con el siguiente comando:

php artisan db:seed

Rutas y controladores

Solo necesitaremos dos rutas, una para acceder a la información desde Vue y la otra para mostrar nuestra aplicación

Route::get('/api/contactos', 'ContactoController@mostrar');
Route::view('/contactos/list', 'list');

En el Controlador ContactoController añadiremos la función mostrar de la siguiente forma:

public function mostrar()
{
        return Contacto::paginate(10);
}

Ahora si probaras de acceder a la ruta localhost/api/contactos verías una respuesta JSON con la información que te da el paginate de Laravel.

Vuejs

Para poder obtener la información tendremos que instalar el paquete vue-resource, para instalarlo utilizaremos el gestor npm:

$ npm install vue-resource

Utilizaremos el componente de Vue que viene por defecto en Laravel para ir mas rápido, así que iremos al fichero ExampleComponent.vue que esta en la ruta js/components y modificaremos tanto la template como el script de forma que quede:

<template>
    <table class="table table-striped">
        <thead>
        <tr>
            <td>ID</td>
            <td>Nombre</td>
            <td>Created At</td>
        </tr>
        </thead>
        <tbody>
        <tr v-for="contacto in contactos.data">
            <td>{{ contacto.id }}</td>
            <td>{{ contacto.nombre }}</td>
            <td>{{ contacto.created_at }}</td>
        </tr>

        <tr>
            <td colspan="5">
                <nav>
                    <ul class="pagination">
                        <li class="page-item" v-show="contactos['prev_page_url']">
                            <a href="#" class="page-link" @click.prevent="getPreviousPage">
                                <span>
                                  <span aria-hidden="true">«</span>
                                </span>
                            </a>
                        </li>
                        <li class="page-item" :class="{ 'active': (contactos['current_page']=== n) }" v-for="n in contactos['last_page']">
                            <a href="#" class="page-link" @click.prevent="getPage(n)">
                                <span >
                                    {{ n }}
                                </span>
                            </a>
                        </li>
                        <li class="page-item" v-show="contactos['next_page_url']">
                            <a href="#" class="page-link" @click.prevent="getNextPage">
                                <span>
                                  <span aria-hidden="true">»</span>
                                </span>
                            </a>
                        </li>
                    </ul>
                </nav>
            </td>
        </tr>

        </tbody>
    </table>
</template>
<script>
    export default {
        data(){
            return {
                contactos: {}
            }
        },
        mounted() {
            this.getContactoList();
        },
        methods: {
            getContactoList(){
                this.$http.get('/api/contactos').then((response)=>{
                    this.$set(this.$data, 'contactos', response.data);
                }, (response)=>{
                    console.log(response.data)
                });
            },
            getPage(page){
                this.$http.get('/api/contactos?page='+page).then((response)=>{
                    this.$set(this.$data, 'contactos', response.data);
                },(response)=>{
                });
            },
            getPreviousPage(){
                this.$http.get(this.contactos['prev_page_url']).then((response)=>{
                    this.$set(this.$data, 'contactos', response.data);
                },(response)=>{
                });
            },
            getNextPage(){
                this.$http.get(this.contactos['next_page_url']).then((response)=>{
                    this.$set(this.$data, 'contactos', response.data);
                },(response)=>{
                });
            },
        }
    }
</script>

Por ultimo solo nos quedaría editar el fichero blade para que muestre el componente, por lo que tendremos que editar el fichero list.blade.php de esta forma:

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-12">
            <div class="card">
                <div class="card-header">Dashboard</div>
                <div class="card-body">
                    <example-component></example-component>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

Con esto solo nos queda volver a compilar los archivos de vue utilizando el comando

$ npm run prod

Al acceder a la ruta localhost/contactos/list ya nos debería salir nuestra tabla con los datos.

Espero que este blog os haya podido ser de ayuda y por cualquier duda podéis dejar un comentario, desde clicko estamos pendientes de vuestras respuestas.

Twitter
Visit Us
Follow Me
LinkedIn
Share