Articles

Vue i Laravel: creeu una aplicació de pàgina única

Laravel és un dels frameworks PHP més populars utilitzats pels desenvolupadors, veiem avui com fer una aplicació de pàgina única amb VueJs.

Abans del llançament de Laravel UI, una de les seves principals característiques era el suport previdefinit per Vue.js de Laravel v5.3 a v6. Vue és un marc d'interfície de JavaScript modern que s'utilitza per crear interfícies d'usuari.

Per què instal·lar Laravel i Vue junts?

Aquests són alguns dels principals avantatges d'utilitzar Laravel amb Vue per crear un flux de treball complet per als vostres projectes:

El codi font es combina en un sol projecte, en lloc de tenir projectes separats per al backend i el frontend
La instal·lació i la configuració són senzilles
Una única distribució pot gestionar tots dos marcs junts

Què és un SPA? (aplicació d'una sola pàgina)

Una aplicació d'una sola pàgina (SPA per abreujar) carrega dinàmicament dades noves d'un servidor web a una pàgina web sense haver d'actualitzar tota la pàgina.

Alguns exemples de llocs web populars que utilitzen SPA inclouen gmail.com i youtube.com; és a dir, els SPA són en gran part omnipresents. La majoria dels taulers d'administració amb els quals podeu treballar diàriament es creen amb SPA.

Avantatges dels SPA:

L'experiència de l'usuari és més flexible
Posa en memòria cau les dades al navegador
Temps de càrrega ràpid


Desavantatges dels SPA:

Pot comprometre el SEO (optimització de motors de cerca)
Problemes de seguretat potencials
Consumeix molts recursos del navegador

Configuració del projecte a Laravel

Aquesta publicació mostrarà com desenvolupar una aplicació de tasques pendents que permeti als usuaris registrar-se per obtenir un compte i afegir tasques.

Per a aquest tutorial, s'utilitza Laravel 9, que requereix PHP 8.1 i Vue 3; també hem de tenir PHP i NGINX instal·lats.

Comencem amb la següent comanda:

composer create-project --prefer-dist laravel/laravel laravel-vue-combo

A continuació, instal·larem les dependències de JavaScript.

npm install

Hem d'instal·lar alguns paquets abans de poder afegir Vue al nostre projecte.

A més, cal instal·lar plugin-vue, ja que Laravel 9 s'envia amb Vite, en lloc de webpack-mix, que era l'anterior paquet de Laravel per a JavaScript. Fem-ho ara:

npm install vue@next vue-loader@next @vitejs/plugin-vue

Obriu el fitxer anomenat vite.config.js i afegir vue() a la configuració:

Butlletí d'innovació
No et perdis les notícies més importants sobre innovació. Registra't per rebre'ls per correu electrònic.
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue'

export default defineConfig({
    plugins: [
        vue(),
        laravel([
            'resources/css/app.css',
            'resources/js/app.js',
        ]),
    ],
});

Editeu el fitxer app.js i el fragment d'arrencada per a l'aplicació Vue 3:

require('./bootstrap');

import {createApp} from 'vue'

import App from './App.vue'

createApp(App).mount("#app")

Creeu un fitxer anomenat App.vue i afegiu el següent:

<template>
  <h1> Hello, Vuejs with Laravel </h1>
</template>
<script>
export default {
  setup() {

   }
}
</script>

Finalment, obriu el fitxer welcome.blade.php situat a la carpeta resources/views i afegiu el següent:

<!DOCTYPE html>
<html>
<head>
 ....
        @vite('resources/css/app.css')
</head>
<body>
  <div id="app"></div>
  @vite('resources/js/app.js')
</body>
</html>

Per previsualitzar la nostra aplicació, hem d'iniciar la nostra aplicació Vue i el servidor Laravel en dos terminals o línies d'ordres diferents:

npm run dev


php artisan serve

Per crear la nostra aplicació de tasques pendents, hem de crear altres fitxers. Vue crearà diverses pàgines, principalment:

  • d'accés
  • per al registre
  • Una pàgina d'inici


Per comunicar-nos amb els punts finals de Laravel, hem d'instal·lar Axios:

npm install axios

vue enrutament

Utilitzant el paquet vue-router, hi ha diverses estratègies d'encaminament que es poden utilitzar a Vue; aquestes estratègies també es coneixen com history models.

Quan un usuari ho sol·licita route com http://localhost:8000/home, que retornarà un error 404 quan s'actualitzi la pàgina, podem confiar en Laravel per detectar qualsevol ruta alternativa i després servir el fitxer Blade que conté la nostra aplicació.

Per aquest motiu, utilitzarem el mode HTML5:

Route::get('/{vue_capture?}', function() {
    return view('welcome');
})->where('vue_capture', '[\/\w\.-]*');
import {createRouter, createWebHistory} from 'vue-router';

const router = createRouter({
    history: createWebHistory(),
    routes: [
        {
            path: '/',
            component: () => import('./pages/Login.vue')
        },
        {
            path: '/register',
            component: () => import('./pages/Register.vue')
        },
        {
            path: '/home',
            component: () => import('./pages/Home.vue')
        }
    ],
})

En aquest exemple gestionem l'autenticació utilitzant Santuari de Laravel, aleshores el testimoni es desa a l'emmagatzematge local.

Perquè altres sol·licituds tinguin èxit, el testimoni es fusiona a la capçalera, cosa que permetrà que Laravel identifiqui l'usuari que fa la sol·licitud.

Aquests són els blocs de codi associats per a tots dos:

<!--Login.vue-->
<template>
    <div class="mx-auto w-4/12 mt-10 bg-blue-200 p-4 rounded-lg">
        <div
            class="bg-white shadow-lg rounded-lg px-8 pt-6 pb-8 mb-2 flex flex-col"
        >
            <h1 class="text-gray-600 py-5 font-bold text-3xl"> Login </h1>
            <ul class="list-disc text-red-400" v-for="(value, index) in errors" :key="index" v-if="typeof errors === 'object'">
                <li>{{value[0]}}</li>
            </ul>
            <p class="list-disc text-red-400" v-if="typeof errors === 'string'">{{errors}}</p>
            <form method="post" @submit.prevent="handleLogin">
            <div class="mb-4">
                <label
                    class="block text-grey-darker text-sm font-bold mb-2"
                    for="username"
                >
                    Email Address
                </label>
                <input
                    class="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker"
                    id="username"
                    type="text"
                    v-model="form.email"
                    required
                />
            </div>
            <div class="mb-4">
                <label
                    class="block text-grey-darker text-sm font-bold mb-2"
                    for="password"
                >
                    Password
                </label>
                <input
                    class="shadow appearance-none border border-red rounded w-full py-2 px-3 text-grey-darker mb-3"
                    id="password"
                    type="password"
                    v-model="form.password"
                    required
                />
            </div>
            <div class="flex items-center justify-between">
                <button
                    class="bg-blue-500 hover:bg-blue-900 text-white font-bold py-2 px-4 rounded"
                    type="submit"
                >
                    Sign In
                </button>
                <router-link
                    class="inline-block align-baseline font-bold text-sm text-blue hover:text-blue-darker"
                    to="register"
                >
                    Sign Up
                </router-link>
            </div>
            </form>
        </div>
    </div>
</template>
export default {
    setup() {
        const errors = ref()
        const router = useRouter();
        const form = reactive({
            email: '',
            password: '',
        })
        const handleLogin = async () => {
            try {
                const result = await axios.post('/api/auth/login', form)
                if (result.status === 200 && result.data && result.data.token) {
                    localStorage.setItem('APP_DEMO_USER_TOKEN', result.data.token)
                    await router.push('home')
                }
            } catch (e) {
                if(e && e.response.data && e.response.data.errors) {
                    errors.value = Object.values(e.response.data.errors)
                } else {
                    errors.value = e.response.data.message || ""
                }
            }
        }

        return {
            form,
            errors,
            handleLogin,
        }
    }
}

Ercole Palmeri

També us pot interessar ...

Butlletí d'innovació
No et perdis les notícies més importants sobre innovació. Registra't per rebre'ls per correu electrònic.

Articles recents

Intervenció innovadora en Realitat Augmentada, amb un visor Apple al Policlínic de Catània

Es va realitzar una operació d'oftalmoplàstia amb el visualitzador comercial Apple Vision Pro a la Policlínica de Catània...

3 maig 2024

Els avantatges de les pàgines per pintar per a nens: un món de màgia per a totes les edats

El desenvolupament de la motricitat fina a través del color prepara els nens per a habilitats més complexes com escriure. Per acolorir...

2 maig 2024

El futur és aquí: com la indústria naviliera està revolucionant l'economia global

El sector naval és una veritable potència econòmica mundial, que ha navegat cap a un mercat de 150 milions...

1 maig 2024

Els editors i OpenAI signen acords per regular el flux d'informació processada per la Intel·ligència Artificial

Dilluns passat, el Financial Times va anunciar un acord amb OpenAI. FT autoritza el seu periodisme de classe mundial...

30 2024 abril