Articoli

Vue e Laravel: creare una Single Page Appliction

Laravel è uno dei framework PHP più popolari utilizzati dagli sviluppatori, vediamo oggi come fare una Single Page Application con VueJs.

Prima del lancio dell’interfaccia utente di Laravel, una delle sue caratteristiche principali era il supporto predefinito per Vue.js da Laravel v5.3 a v6. Vue è un moderno framework frontend JavaScript utilizzato per creare interfacce utente.

Perché installare Laravel e Vue insieme ?

Ecco alcuni dei principali vantaggi dell’utilizzo di Laravel con Vue per creare un flusso di lavoro completo per i tuoi progetti:

Il codice sorgente è combinato in un unico progetto, invece di avere progetti separati per il backend e il frontend
L’installazione e la configurazione sono semplici
Una singola distribuzione può gestire entrambi i framework insieme

Cos’è una SPA? (single-page application)

Una single-page application (in breve SPA) carica dinamicamente nuovi dati da un server Web a una pagina Web senza dover aggiornare l’intera pagina.

Esempi di siti Web popolari che utilizzano SPA includono gmail.com e youtube.com: in altre parole, le SPA sono in larga misura onnipresenti. La maggior parte dei dashboard di amministrazione con cui potresti lavorare quotidianamente viene creata utilizzando SPA.

Vantaggi delle SPA:

L’esperienza utente è più flessibile
Memorizza nella cache i dati nel browser
Tempo di caricamento rapido


Svantaggi delle SPA:

Può compromettere la SEO (ottimizzazione per i motori di ricerca)
Potenziali problemi di sicurezza
Consuma molte risorse del browser

Configurazione progetto in Laravel

Questo post dimostrerà come sviluppare un’app da fare che consenta agli utenti di registrarsi per un account e aggiungere attività.

Per questo tutorial viene utilizzato Laravel 9, che richiede PHP 8.1 e Vue 3; dobbiamo anche avere PHP e NGINX installati.

Iniziamo con il seguente comando:

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

Successivamente, installeremo le dipendenze JavaScript.

npm install

Dobbiamo installare alcuni pacchetti prima di poter aggiungere Vue al nostro progetto.

Inoltre, deve essere installato plugin-vue, poiché Laravel 9 viene fornito con Vite, anziché webpack-mix, che era il precedente bundler di Laravel per JavaScript. Facciamolo ora:

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

Apri il file chiamato vite.config.js e aggiungi vue() alla configurazione:

Newsletter sull’Innovazione
Non perderti le notizie più importanti sull'Innovazione. Iscriviti per riceverle via e-mail.
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',
        ]),
    ],
});

Modifica il file app.js e lo snippet per il bootstrap dell’app Vue 3:

require('./bootstrap');

import {createApp} from 'vue'

import App from './App.vue'

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

Crea un file chiamato App.vue e aggiungi quanto segue:

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

   }
}
</script>

Infine, apri il file welcome.blade.php che si trova nella cartella resources/views e aggiungi quanto segue:

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

Per visualizzare l’anteprima della nostra app, dobbiamo avviare la nostra app Vue e il server Laravel su due diversi terminali/righe di comando:

npm run dev


php artisan serve

Per creare la nostra app da fare, dobbiamo creare altri file. Vue creerà più pagine, principalmente:

  • di accesso
  • per la registrazione
  • Una pagina iniziale


Per comunicare con gli endpoint Laravel, dobbiamo installare Axios:

npm install axios

Vue routing

Utilizzando il pacchetto vue-router, ci sono varie strategie di routing che possono essere utilizzate in Vue; queste strategie sono anche conosciute come history models.

Quando un utente richiede route come http://localhost:8000/home, che restituirà un errore 404 quando la pagina viene aggiornata, possiamo fare affidamento su Laravel per rilevare eventuali route di fallback e quindi servire il file Blade che contiene la nostra app.

Per questo motivo, utilizzeremo la modalità 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')
        }
    ],
})

In questo esempio si gestisce l’autenticazione utilizzando Laravel Sanctum, quindi viene salvato il token nell’archivio locale.

Affinché altre richieste vadano a buon fine, il token viene unito all’intestazione, che consentirà all’utente che effettua la richiesta di essere identificato da Laravel.

Qui di seguito i blocchi di codice associati per entrambi:

<!--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

Potrebbe interessarti anche…

Newsletter sull’Innovazione
Non perderti le notizie più importanti sull'Innovazione. Iscriviti per riceverle via e-mail.

Articoli recenti

Idea Brillante: Bandalux presenta Airpure®, la tenda che purifica l’aria

Risultato della costante innovazione tecnologica e all'impegno nei confronti dell'ambiente e del benessere delle persone. Bandalux presenta Airpure®, una tenda…

12 Aprile 2024

Design Patterns V.s. principi S.O.L.I.D., vantaggi e svantaggi

I design pattern sono soluzioni specifiche di basso livello a problemi ricorrenti nella progettazione del software. I design pattern sono…

11 Aprile 2024

Magica, l’app iOS che semplifica la vita degli automobilisti nella gestione del proprio veicolo

Magica è l'app per iPhone che rende la gestione dei veicoli semplice ed efficiente, aiutando gli automobilisti a risparmiare e…

11 Aprile 2024

Grafici di Excel, quali sono, come creare un grafico e come scegliere il grafico ottimale

Un grafico di Excel è un elemento visivo che rappresenta i dati presenti in un foglio di lavoro di Excel.…

9 Aprile 2024