Laravel 5, Vue.js y Ajax

Bien, en esta publicación vamos a ver cómo integrar Vue a un proyecto hecho en Laravel. El ejemplo será el siguiente: vamos a administrar una lista de notas con Ajax. Será muy simple, sin embargo llevaremos a cabo una serie de pasos como crear migraciones, compilar un archivo .Vue, usar la librería de vue-resource, etc.

En primer lugar, antes de empezar debemos tener instalado lo siguiente:

  • Composer
  • Node.js

En el caso de Node.js, la instalación del mismo, nos permitirá usar el comando npm. Podés probar en tu computadora, abriendo una terminal (símbolo de sistema en Windows) y escribir lo siguiente:

npm --info

Si te devuelve un error, es porque nunca instalaste Node. Es un buen momento para hacerlo:

https://nodejs.org/es/

Creación del proyecto

Abrimos la consola y creamos nuestro proyecto Laravel:

composer create-project laravel/laravel laravel_vuejs --prefer-dist

Una vez instalado, vamos a la raíz del proyecto y buscamos un archivo llamado: ‘package.json’, donde van las dependencias (‘devDependencies’), agregamos vue y vue-resource:

"vue": "^2.1.10", 
"vue-resource": "^1.3.4"

Probablemente ya exista la primera (vue), de ser así, la dejamos y sólo agregamos ‘vue-resource’

Luego volvemos a la consola y entramos en nuestro proyecto:

cd laravel_vuejs

Y ejecutamos el comando de node que nos va a instalar estas dependencias:

npm install

(Puede tardar bastante, a esperar…)

Modelo y Migración

Primero vamos creamos una base de datos, en mi caso se va a llamar ‘laravel_vuejs’. Luego en el raíz de nuestro proyecto editamos .env:

DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_vuejs
DB_USERNAME=root
DB_PASSWORD=

(Escribimos los datos para conectar a nuestra base de datos)

Volvemos a la consola y escribimos lo siguiente:

php artisan make:migration create_notas_table

Vamos al archivo que acabamos, en database/migrations de crear y le cambiamos los métodos up() y down() por:

public function up() 
{ 
   Schema::create('notas', function(Blueprint $table){ 
      $table->increments('id'); 
      $table->string('descripcion'); 
      $table->timestamps(); 
   }); 
}
public function down() 
{ 
   Schema::dropIfExists('notas'); 
}

Volvemos a la consola y creamos la tabla:

php artisan migrate

Y por último el modelo:

php artisan make:model Nota

 

Controlador y Rutas

Vamos a la consola y creamos el controlador:

php artisan make:controller NotasController

Una vez creado, nos dirigimos al controlador en app/Http/Controllers, y lo editamos con el siguiente código:

use App\Nota;
class NotasController extends Controller  {
   public function notas(){
      return view('notas');  
   }  
   public function mostrarNotas(){
      return Nota::all();  
   }
   public function guardarNota(Request $request){
      $nota = new Nota();
      $nota->descripcion = $request->input('descripcion');
      $nota->save();
      return $this->mostrarNotas();
   }
   public function eliminarNota(Request $request){
      $nota = Nota::find($request->input('id'));
      $nota->delete();
      return $this->mostrarNotas();
   }
}

Analicemos el código. Los métodos:

  • notas(): Carga una vista (GET)
  • mostrarNotas(): Devuelve un json con las notas cargadas (GET)
  • guardarNota(): Recibe una nota, la guarda y devuelve las notas actualizadas (POST)
  • eliminarNota(): Recibe una nota, la elimina y devuelve las notas actualizadas (POST)

Ahora nos queda agregar las rutas en routes/web.php:

Route::get('/notas', 'NotasController@notas'); 
Route::get('/mostrar_notas', 'NotasController@mostrarNotas'); 
Route::post('/guardar_nota', 'NotasController@guardarNota'); 
Route::post('eliminar_nota', 'NotasController@eliminarNota');

 

Vista

Ahora vamos a crear la vista para administrar las notas, dentro de resources/views con el nombre ‘notas.blade.php’,:

<!doctype html> 
<html lang="{{ config('app.locale') }}"> 
 <head> 
 <meta charset="utf-8"> 
 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 
 <meta name="viewport" content="width=device-width, initial-scale=1"> 
 <!-- CSRF Token --> 
 <meta name="csrf-token" content="{{ csrf_token() }}"> 
 <title>Laravel y Vue</title> 
 <link rel="stylesheet" href="{{ elixir('css/app.css') }}"> 
 </head> 
 <body> 
    <div id="app" class="container"> 
       <h1> Notas </h1> 
       <notas></notas> 
    </div> 
    <input type="hidden" id="csrf_token" value="{{ csrf_token() }}" /> 
    <script src="{{ elixir('js/app.js') }}"></script> 
 </body> 
</html>

Vamos a detenernos para entender algunas líneas de este código:

Cargamos una hoja de estilos, esto tiene que ver más con la parte estética, no influye en el funcionamiento:

<link rel="stylesheet" href="{{ elixir('css/app.css') }}">

Incluimos el componente:

<notas></notas>

Aunque aún no lo hemos creado, esta es la forma de incluir componentes. Toda la parte visual de la administración de notas se incluye con las etiquetas con dicho nombre. Etiquetas que por supuesto no son de html, sino inventadas por el desarrollador.

Incluimos un campo de entrada con el token:

<input type="hidden" id="csrf_token" value="{{ csrf_token() }}" />

Aunque las peticiones por POST las haremos con ajax, de cualquier manera tenemos que enviar el token en cada envío, ya que Laravel por cuestiones de seguridad espera por cabecera este dato.

Y por último incluimos el .js base de la aplicación, el cual va a incluir por ejemplo vue, vue-resource y los componentes que vayamos creando:

<script src="{{ elixir('js/app.js') }}"></script>

 

Creando nuestro componente

Antes de continuar vamos a detenernos en algo importante: ¿Qué es un componente? Un componente es código HTML extendido. Va a estar divido en dos partes: una vista y un controlador. La vista es el código HTML, mientras que el controlador es el código Javascript que le da funcionalidad a esa vista.

Creo que a estas alturas la mayoría deben saber de qué se trata, pero si no es así podés verlo de la siguiente forma: imaginate un tablero que contiene una pantalla, botones y palancas. La vista serían justamente esos elementos que en conjunto forman el tablero, pero será el controlador quien por ejemplo guarde la información que vemos  y no vemos por pantalla (datos), o que al pulsar en un botón suceda algo (métodos)

La ventaja del componente es que podemos encapsular un apartado visual y reutilizarlo cada vez que queramos.

Para crear nuestro componente primero tenemos que incluir las librerías, entonces vamos a resources/assets/js/app.js y copiamos el siguiente código:

require('./bootstrap'); 
window.Vue = require('vue'); 
Vue.use(require('vue-resource')); 
Vue.http.headers.common['X-CSRF-TOKEN'] = document.getElementById('csrf_token').value;

Aquí incluimos bootstrap y vue. También vue-resource la librería que nos va a permitir hacer peticiones http. Y finalmente agregamos el token para no tener que preocuparnos en cada petición por POST.

Y más abajo incluimos el componente que aún no hemos creado:

Vue.component('notas', require('./components/Notas.vue'));

Vamos a resources/assets/js/components y creamos un archivo llamado Notas.vue con el siguiente código:

<template> 
   <form> 
      <div class="form-group"> 
         <label for="exampleInputEmail1"> Descripción </label> 
         <input type="text" class="form-control" v-model="nota_temp.descripcion" /> 
      </div> 
      <button type="button" class="btn btn-primary" v-on:click="guardarNota()"> Guardar nota </button> 
      <hr /> 
      <ul> 
         <li v-for="n in notas"> 
            {{ n.descripcion }} 
            | 
            <a href="#" class="text text-danger" v-on:click="eliminarNota(n)"> Eliminar </a> 
         </li> 
      </ul> 
   </form> 
</template> 
 
<script> 
 export default { 
    data(){ 
       return { 
          nota_temp: { 
             descripcion: '' 
          }, 
          notas: [] 
       }
    }, 
    methods: { 
       mostrarNotas(){ 
          this.$http.get('/mostrar_notas').then(response => { 
             this.notas = response.body; 
          }, response => { 
             alert('Error'); 
          }); 
       }, 
       guardarNota(){ 
          this.$http.post('/guardar_nota', { 
             descripcion: this.nota_temp.descripcion 
          }).then(response => { 
             this.nota_temp.descripcion = ''; 
             this.notas = response.body; 
          }, response => { 
             alert('Error'); 
          }); 
       }, 
       eliminarNota(p_nota){ 
          this.$http.post('/eliminar_nota', { 
             id: p_nota.id 
          }).then(response => { 
             this.notas = response.body; 
          }, response => { 
             alert('Error'); 
          }); 
       } 
    },
    created(){ 
       this.mostrarNotas(); 
    } 
 } 
</script>

Finalmente volvemos a la consola y compilamos el componente que acabamos de crear:

npm run dev

(Cada cambio requiere que hagamos esto)

Descargar ejemplo

Redes sociables

    2 Replies to “Laravel 5, Vue.js y Ajax”

    Deja un comentario

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

    *