Diferencia entre revisiones de «Usuario:ManuelRomero/Laravel/JetstreamInertia»
De WikiEducator
(→Instación) |
|||
(24 revisiones intermedias por el mismo usuario no mostrado) | |||
Línea 17: | Línea 17: | ||
*Cuando Inertia realiza una visita XHR, el servidor detecta que se trata de una visita Inertia y, en lugar de devolver una respuesta HTML completa, devuelve una respuesta JSON con el nombre del componente de la página JavaScript y los datos (props). | *Cuando Inertia realiza una visita XHR, el servidor detecta que se trata de una visita Inertia y, en lugar de devolver una respuesta HTML completa, devuelve una respuesta JSON con el nombre del componente de la página JavaScript y los datos (props). | ||
===El protocolo=== | ===El protocolo=== | ||
− | *Lo primero que ocurre en una aplicacion inertia es que se solicita una página html completa nomal | + | *Lo primero que ocurre en una aplicacion inertia es que se solicita una página html completa nomal. |
− | + | *La primera vez, responde el servidor para entregar la página '''''app.blade.php'''''. Esto inicia la aplicación. Sucesivas veces, se renderizará una vista javascript en nuestro caso componente vue. | |
− | *Esta página tendrá los elementos js y css. El div principal será el punto de montaje de la aplicación y contendrá un elemento especial <data-page> cuyo valor es un json que codifica un '''''page object''''' para la página inicial. | + | *Esta página, ''''app.blade.php''''' tendrá los elementos js y css. El div principal será el punto de montaje de la aplicación y contendrá un elemento especial <data-page> cuyo valor es un json que codifica un '''''page object''''' para la página inicial. |
− | Inertia utiliza esta información para iniciar el lado del cliente y mostrar el componente de página inicial. | + | *Este objeto contiene 4 elementos: |
+ | #'''''component''''': The name of the JavaScript page component. | ||
+ | #'''''props''''': The page props (data). | ||
+ | #'''''url''''': The page url. | ||
+ | #'''''version''''': The current asset version. | ||
+ | *Inertia utiliza esta información para iniciar el lado del cliente y mostrar el componente de página inicial. | ||
+ | [[Archivo:carga_inertia.png|600px|center]] | ||
+ | *Gracias a este objeto, | ||
<source lang=html5> | <source lang=html5> | ||
Línea 36: | Línea 43: | ||
</html> | </html> | ||
</source> | </source> | ||
+ | |||
===Instación=== | ===Instación=== | ||
*El proceso de instalación está descrito en la página oficial de forma muy intuitiva. Vamos a hacer la instalación para '''''laravel''''' y usaremos '''''vue''''' en el cliente. | *El proceso de instalación está descrito en la página oficial de forma muy intuitiva. Vamos a hacer la instalación para '''''laravel''''' y usaremos '''''vue''''' en el cliente. | ||
====Servidor==== | ====Servidor==== | ||
+ | <br /> | ||
{{MRM_Actividad|Title=1.-Creamos un proyecto en laravel| | {{MRM_Actividad|Title=1.-Creamos un proyecto en laravel| | ||
<source lang=bash> | <source lang=bash> | ||
Línea 67: | Línea 76: | ||
</source> | </source> | ||
}} | }} | ||
+ | ====Cliente==== | ||
+ | <br /> | ||
+ | {{MRM_Actividad|Title=1.-Instalamos el paquete inertia para el front| | ||
+ | *Instalamos tanto inertia como vue-3 que vamos a usar en este caso | ||
+ | *Se pueden usar otros frameworks (tanto en servidor como cliente, ver página oficial) | ||
+ | *La instalación la hacemos vía '''''npm''''' | ||
+ | <source lang=bash> | ||
+ | npm install @inertiajs/inertia @inertiajs/inertia-vue3 | ||
+ | </source> | ||
+ | }} | ||
+ | {{MRM_Actividad|Title=2.-Instalamos el cargador de vue| | ||
+ | *Si ejecutamos '''''npm run dev''''' el propio sistema nos informa que debemos instalar paquetes adicionales | ||
+ | <br /> | ||
+ | [[archivo:inertia_cliente_1.png|700px]] | ||
+ | <br /> | ||
+ | *Instalamos | ||
+ | <source lang=bash> | ||
+ | npm install @vue/compiler-sfc vue-loader@^16.2.0 --save-dev --legacy-peer-deps | ||
+ | </source> | ||
+ | }} | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | Instalamos un paquete para barra de progreso (opcional)| | ||
+ | |||
+ | |||
+ | {{MRM_Actividad|Title=5.-Instalamos un paquete para barra de progreso (opcional)| | ||
+ | *Dado que inertia trabaja con llamadas XHR (ajax), para que el usuario vea que la página está cambiando o se está cargando, es una buena experienica de usuario mostrar de alguna forma una marca de progreso al usuario mientras la página se carga. | ||
+ | *Normalmente la carga será rápida (vía ajax suele ser rápido), pero los accesos a bases de datos, etc, pueden insertar un delay, y si no cambia nada en la pantalla el usuario podrá pensar que no funciona y dará muchas veces click. | ||
+ | *Primero instalamos, posteriormente mostraremos su uso. | ||
+ | <source lang=bash> | ||
+ | npm install @inertiajs/progress | ||
+ | </source> | ||
+ | }} | ||
+ | |||
+ | ====Instalando taildwind==== | ||
+ | <br /> | ||
+ | {{MRM_Actividad|Title=1.-Instalnado en el cliente | | ||
+ | <source lang=bash> | ||
+ | npm install -D tailwindcss@latest postcss@latest autoprefixer@latest | ||
+ | </source> | ||
+ | }} | ||
+ | {{MRM_Actividad|Title=2.-Creando el fichero de configuración tailwind.config.js| | ||
+ | <source lang=bash> | ||
+ | npx tailwindcss init | ||
+ | </source> | ||
+ | }} | ||
+ | |||
+ | {{MRM_Actividad|Title=3.-Agregar acciones para eliminar estilos no usados en produccion| | ||
+ | <source lang=bash> | ||
+ | purge: [ | ||
+ | './resources/**/*.blade.php', | ||
+ | './resources/**/*.js', | ||
+ | './resources/**/*.vue', | ||
+ | ], | ||
+ | darkMode: false, // or 'media' or 'class' | ||
+ | </source> | ||
+ | }} | ||
+ | {{MRM_Actividad|Title=4.-Modificar el fichero webpack añadiendo el framework taildwind| | ||
+ | <source lang=bash> | ||
+ | |||
+ | .postCss('resources/css/app.css', 'public/css', [ | ||
+ | require ("tailwindcss"), | ||
+ | // | ||
+ | ]); | ||
+ | </source> | ||
+ | }} | ||
+ | {{MRM_Actividad|Title=5.-Especificamos en el fichero app.css el uso del framework| | ||
+ | *Fichero '''''./resources/css/app.css''''' | ||
+ | <source lang=bash> | ||
+ | /* ./resources/css/app.css */ | ||
+ | @tailwind base; | ||
+ | @tailwind components; | ||
+ | @tailwind utilities; | ||
+ | </source> | ||
+ | }} | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | {{MRM_Actividad|6.- Para usarlo especificamos la ubicación del fichero css| | ||
+ | |||
+ | <source lang=html5> | ||
+ | <!doctype html> | ||
+ | <head> | ||
+ | <!-- ... ---> | ||
+ | <meta charset="UTF-8" /> | ||
+ | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
+ | <link href="{{ asset('css/app.css') }}" rel="stylesheet"> | ||
+ | </head> | ||
+ | </source> | ||
+ | |||
+ | }} | ||
+ | |||
+ | ====Poniendo el proyecto en fucionamiento==== | ||
+ | *Una vez realizada la instalación de los paquetes que necesitamos, vamos a crear un proyecto base y verificar su funcionamiento. | ||
+ | |||
+ | =====Servidor===== | ||
+ | <br /> | ||
+ | {{MRM_Actividad|Title=1.-Creamos la página de carga inicial '''''app.blade.php'''''| | ||
+ | *Inertia, como hemos indicado no va a realizar solicitudes de páginas al servidor, se van a renderizar páginas js con vue. | ||
+ | *El servidor debe de entregar una primera página que será una vista de blade y la llamaremos app.blade.php | ||
+ | *Si queremos usar otro nombre lo modificaremos usando | ||
+ | <source lang=php> | ||
+ | Inertia::setRootView(). | ||
+ | </source> | ||
+ | *Iguamente se puede modificar el atributo protegido en '''''Middleware/HandleInertiaRequest.php''''' | ||
+ | <source lang=php> | ||
+ | protected $rootView = 'app'; | ||
+ | </source> | ||
+ | *Esta plantilla debe de contener la directiva '''''@inertia''''', la cual cargará un '''''objeto de página''''. Esta plantilla será una página html5 y la ubicación de los ficheros '''''css y js''''': | ||
+ | <source lang=html5> | ||
+ | <!DOCTYPE html> | ||
+ | <html> | ||
+ | <head> | ||
+ | <meta charset="utf-8" /> | ||
+ | <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> | ||
+ | <link href="{{ mix('/css/app.css') }}" rel="stylesheet" /> | ||
+ | <script src="{{ mix('/js/app.js') }}" defer></script> | ||
+ | </head> | ||
+ | <body> | ||
+ | @inertia | ||
+ | </body> | ||
+ | </html> | ||
+ | </source> | ||
+ | }} | ||
+ | |||
+ | {{MRM_Actividad|Title=2.-Publicar el middleware| | ||
+ | *Ahora debemos de pulbicar el middleware que hemos instalado previamente para poderlo utilizar en el proyecto. | ||
+ | *Este middleware contiene dos métodos muy útiles (veremos posteriormente) | ||
+ | *1.-'''''version()''''' . Útil para ver la versión de los ficherso css, de forma que si cambian estos ficheros, podamos saberlo para realizar una carga de la página inicial y cargar los css correctos | ||
+ | *2.-'''''share()'''''. Útil para compartir datos entre las diferentes vistas, como podría ser el nombre de usuario. | ||
+ | <source lang=bash> | ||
+ | php artisan inertia:middleware | ||
+ | </source>. | ||
+ | }} | ||
+ | <br /> | ||
+ | =====Cliente===== | ||
+ | {{MRM_Actividad|Title=2.-Crear app.js| | ||
+ | *En '''''./resource/js/app.js''''' | ||
+ | *Todos los componenetes estarán ubicados en la carpeta '''''Pages''''' según especificamos | ||
+ | <source lang=javascript> | ||
+ | import { createApp, h } from 'vue' | ||
+ | import { createInertiaApp } from '@inertiajs/inertia-vue3' | ||
+ | |||
+ | createInertiaApp({ | ||
+ | resolve: name => require(`./Pages/${name}`), | ||
+ | setup({ el, App, props, plugin }) { | ||
+ | createApp({ render: () => h(App, props) }) | ||
+ | .use(plugin) | ||
+ | .mount(el) | ||
+ | }, | ||
+ | }) | ||
+ | </source> | ||
+ | *Creamos la carpeta '''''Pages''''' en el directorio actual: '''''./resources/js/Pages''''' | ||
+ | }} | ||
+ | |||
+ | =====Manejo de rutas y vistas===== | ||
+ | <br /> | ||
+ | {{MRM_Web| | ||
+ | https://sebastiandedeyne.com/handling-routes-in-a-laravel-inertia-application/ | ||
+ | }} | ||
+ | *Tenemos diferentes formas de especificar la vista que queremos cargar ante una solicitud | ||
+ | *Todas las solicitudes serán solicitudes ajax menos la primera vez que se inicie la aplicación. Estas acciones serán transparentes para el programador. | ||
+ | *'''''La renderización serán de páginas vue no de plantillas blade''''' | ||
+ | [[Archivo:carga_inertia.png|center|600px]] | ||
+ | *El proceso de ruteo lo gestiona laravel '''''web.php''''' | ||
+ | *Podemos especifiar directamente la página vue que quiero cargar. Por ejemplo, podemos cargar dos vistas vue: | ||
+ | <source lang=php> | ||
+ | Route::inertia('/pagina1', 'componente_pagina1'); | ||
+ | Route::inertia('/pagina2', 'componente_pagina2'); | ||
+ | </source> | ||
+ | *Donde '''''componente_pagina1''''', y '''''componente_pagina2''''' son componentes vue | ||
+ | <source lang=php> | ||
+ | <template> | ||
+ | <h1>Esta es una vista básica de la página 1</h1> | ||
+ | </template> | ||
+ | {{MRM_Pregunta| | ||
+ | ;No sé por qué si pongo una página que no existe, funciona y me retorna solo la página app.blade.php | ||
+ | Pendiente de reivsar la facade Route::inertia() | ||
+ | }} | ||
+ | <script> | ||
+ | export default { | ||
+ | name: "vista_basica1" | ||
+ | } | ||
+ | </script> | ||
+ | <style scoped> | ||
+ | </style> | ||
+ | </source> | ||
+ | <source lang=php> | ||
+ | <template> | ||
+ | <h1>Esta es una vista básica de la página 2</h1> | ||
+ | </template> | ||
+ | |||
+ | <script> | ||
+ | export default { | ||
+ | name: "vista_basica1" | ||
+ | } | ||
+ | </script> | ||
+ | <style scoped> | ||
+ | </style> | ||
+ | </source> | ||
+ | |||
+ | {{MRM_Actividad|Title=2.-Ca.| | ||
+ | *La carga de las vistas las hará larevel con la facade '''''render''''' | ||
+ | *Vemos un ejemplo: | ||
+ | |||
+ | *1.-'''''El ruteo en web.php''''' | ||
+ | <source lang=php> | ||
+ | |||
+ | </source> | ||
+ | *2.- '''''El controlador ''''' | ||
+ | *Creamos un controlador llamado por ejemplo '''''ControlerPpal'''' | ||
+ | <source lang=php> | ||
+ | php artisan make:controller ControllerPpal | ||
+ | |||
+ | </source> | ||
+ | *3.- '''''La vista''''' | ||
+ | }} | ||
+ | =====Cliente===== | ||
+ | <br /> | ||
+ | {{MRM_Actividad|Title=1.-Instalamos paquetes de vue en el cliente| | ||
+ | <source lang=bash> | ||
+ | npm install @vue/compiler-sfc vue-loader@^16.2.0 --save-dev --legacy-peer-deps | ||
+ | </source> | ||
+ | }} | ||
+ | {{MRM_Actividad|Title=2.-Modificamos el fichero webpack| | ||
+ | *Ahora le indicamos en el fichero webpack que vamos a usar vue. | ||
+ | *Para ello añadimos el framework la línea de '''''vue''''' | ||
+ | <source lang=bash> | ||
+ | |||
+ | mix.js('resources/js/app.js', 'public/js') | ||
+ | .postCss('resources/css/app.css', 'public/css', [ | ||
+ | // | ||
+ | ]) | ||
+ | .vue({ runtimeOnly: true }) | ||
+ | </source> | ||
+ | }} | ||
+ | {{MRM_Actividad|Title=3.-Instalamos tailwindcss (opcional)| | ||
+ | *Este framework de css no es necesario ni tiene que ver con inertia. | ||
+ | *Lo instalo porque lo uso como framework de css | ||
+ | <source lang=bash> | ||
+ | </source> | ||
+ | }} | ||
====Cliente==== | ====Cliente==== | ||
+ | <br /> | ||
+ | ===Instalación desde consola con parámetros=== | ||
+ | <source lang=bash> | ||
+ | laravel new practicas --jet | ||
+ | </source> | ||
+ | *Entonces eliges la opción inertia cuando lo solicite | ||
+ | ===Form=== | ||
+ | {{MRM_Web| | ||
+ | https://inertiajs.com/forms | ||
+ | }} | ||
+ | |||
+ | *Creamos un componente vue con el formulario en el template | ||
+ | <source lang=html5> | ||
+ | <template> | ||
+ | <form @submit.prevent="submit"> | ||
+ | <label for="ficheroPracticaZip">Selecciona fichero zip con las prácticas( bajado de moodle)</label> | ||
+ | <input id="ficheroPracticaZip" v-model="form.ficheroPracticaZip"/> | ||
+ | <label for="grupo">Grupo </label> | ||
+ | <input id="grupo" v-model="form.grupo"/> | ||
+ | <label for="practica">Practica:</label> | ||
+ | <input id="practica" v-model="form.practica"/> | ||
+ | <button type="submit">Submit</button> | ||
+ | </form> | ||
+ | </template> | ||
+ | </source> |
Última revisión de 23:07 2 ene 2022
Contenido
Qué es Inertia
- Una librería para construir una aplicación web gestionada desde el servidor. Se le conoce como modern monolith. Se puede usar además de con Laravel con otras herramientas (DJango, Rail, Ruby,...)
- Inertia le permite crear una aplicación de una sola página completamente basada en JavaScript sin complejidad adicional.
- Inertia funciona mucho más como una aplicación clásica renderizada del lado del servidor:
- Creas controladores
- Obtienes datos de la base de datos (a través de tu ORM)
- Renderizas vistas.que son componentes de página de JavaScript.
Cómo trabaja
- Trabajando con Inertia, vamos a usar el framework del servidor como siempre. En nuestro caso seguimos usando laravel con sus controladores, rutas, authetificadores , ...
- Inertia es esencialmente una biblioteca de enrutamiento del lado del cliente. Le permite realizar visitas a la página sin forzar una recarga completa de la página.
Para ver una página sin necesidad de realizar la carga completa, usamos el componente <inertia-link>.
- También se puede realizar una llamada usando Inertia.visit()
- Cuando tenemos una ancla con la envoltura <inertia-link>, se produce una solicitud XHR al servidor.
- Cuando Inertia realiza una visita XHR, el servidor detecta que se trata de una visita Inertia y, en lugar de devolver una respuesta HTML completa, devuelve una respuesta JSON con el nombre del componente de la página JavaScript y los datos (props).
El protocolo
- Lo primero que ocurre en una aplicacion inertia es que se solicita una página html completa nomal.
- La primera vez, responde el servidor para entregar la página app.blade.php. Esto inicia la aplicación. Sucesivas veces, se renderizará una vista javascript en nuestro caso componente vue.
- Esta página, 'app.blade.php tendrá los elementos js y css. El div principal será el punto de montaje de la aplicación y contendrá un elemento especial <data-page> cuyo valor es un json que codifica un page object para la página inicial.
- Este objeto contiene 4 elementos:
- component: The name of the JavaScript page component.
- props: The page props (data).
- url: The page url.
- version: The current asset version.
- Inertia utiliza esta información para iniciar el lado del cliente y mostrar el componente de página inicial.
- Gracias a este objeto,
<html> <head> <title>My app</title> <link href="/css/app.css" rel="stylesheet"> <script src="/js/app.js" defer></script> </head> <body> <div id="app" data-page='{"component":"Event","props":{"event":{"id":80,"title":"Birthday party","start_date":"2019-06-02","description":"Come out and celebrate Jonathan's 36th birthday party!"}},"url":"/events/80","version":"c32b8e4965f418ad16eaebba1d4e960f"}'></div> </body> </html>
Instación
- El proceso de instalación está descrito en la página oficial de forma muy intuitiva. Vamos a hacer la instalación para laravel y usaremos vue en el cliente.
Servidor
Cliente
Instalamos un paquete para barra de progreso (opcional)|
npm install @inertiajs/progress
|
Instalando taildwind
Poniendo el proyecto en fucionamiento
- Una vez realizada la instalación de los paquetes que necesitamos, vamos a crear un proyecto base y verificar su funcionamiento.
Servidor
Inertia::setRootView().
protected $rootView = 'app';
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> <link href="{{ mix('/css/app.css') }}" rel="stylesheet" /> <script src="{{ mix('/js/app.js') }}" defer></script> </head> <body> @inertia </body> </html>
|
php artisan inertia:middleware
|
Cliente
import { createApp, h } from 'vue' import { createInertiaApp } from '@inertiajs/inertia-vue3' createInertiaApp({ resolve: name => require(`./Pages/${name}`), setup({ el, App, props, plugin }) { createApp({ render: () => h(App, props) }) .use(plugin) .mount(el) }, })
|
Manejo de rutas y vistas
- Tenemos diferentes formas de especificar la vista que queremos cargar ante una solicitud
- Todas las solicitudes serán solicitudes ajax menos la primera vez que se inicie la aplicación. Estas acciones serán transparentes para el programador.
- La renderización serán de páginas vue no de plantillas blade
- El proceso de ruteo lo gestiona laravel web.php
- Podemos especifiar directamente la página vue que quiero cargar. Por ejemplo, podemos cargar dos vistas vue:
Route::inertia('/pagina1', 'componente_pagina1'); Route::inertia('/pagina2', 'componente_pagina2');
- Donde componente_pagina1, y componente_pagina2 son componentes vue
<template> <h1>Esta es una vista básica de la página 1</h1> </template> {{MRM_Pregunta| ;No sé por qué si pongo una página que no existe, funciona y me retorna solo la página app.blade.php Pendiente de reivsar la facade Route::inertia() }} <script> export default { name: "vista_basica1" } </script> <style scoped> </style>
<template> <h1>Esta es una vista básica de la página 2</h1> </template> <script> export default { name: "vista_basica1" } </script> <style scoped> </style>
Cliente
Cliente
Instalación desde consola con parámetros
laravel new practicas --jet
- Entonces eliges la opción inertia cuando lo solicite
Form
- Creamos un componente vue con el formulario en el template
<template> <form @submit.prevent="submit"> <label for="ficheroPracticaZip">Selecciona fichero zip con las prácticas( bajado de moodle)</label> <input id="ficheroPracticaZip" v-model="form.ficheroPracticaZip"/> <label for="grupo">Grupo </label> <input id="grupo" v-model="form.grupo"/> <label for="practica">Practica:</label> <input id="practica" v-model="form.practica"/> <button type="submit">Submit</button> </form> </template>