Articoli

Creazione di una App CRUD con Laravel e Vue.js

In questo tutorial vediamo insieme come scrivere il codice di una App CRUD di esempio, con Laravel e Vue.js.

La Single Page Application ci permetterà di completare un ciclo di operazioni base su DB: crea, leggi, aggiorna ed elimina con Vue.js , Vue Router e Laravel Framework .

Al giorno d’oggi, i framework JS più popolari sono Angular JS e Vue JS. Angular JS e Vue JS sono framework JS molto user-friendly e più popolari. Fornisce la gestione dell’intero progetto o applicazione senza aggiornare la pagina e la potente convalida jquery.

Vue viene fornito preconfezionato con Laravel (insieme a Laravel Mix , un eccellente strumento di creazione basato su webpack ) e consente agli sviluppatori di iniziare a creare complesse applicazioni a pagina singola senza preoccuparsi di transpiler, pacchetti di codice, mappe di origine o altri aspetti “sporchi” del moderno sviluppo del frontend.

Requisiti del server

Php 7.4

Laravel 8.x

MySQL

Installa il progetto Laravel

Innanzitutto, apri Terminale ed esegui il seguente comando per creare un nuovo progetto laravel:

composer create-project --prefer-dist laravel/laravel crud-spa

oppure, se hai installato Laravel Installer come dipendenza globale del compositore:

laravel new crud-spa

Configura i dettagli del database:

Dopo l’installazione Vai alla directory principale del progetto, apri il file .env e imposta i dettagli del database come segue:

DB_CONNECTION=mysql 
DB_HOST=127.0.0.1 
DB_PORT=3306 
DB_DATABASE=<DATABASE NAME>
DB_USERNAME=<DATABASE USERNAME>
DB_PASSWORD=<DATABASE PASSWORD>

Installare le dipendenze NPM

Esegui il seguente comando per installare le dipendenze front-end:

npm install

Successivamente, installa vue ,  vue-router  e vue-axios . Vue-axios verrà utilizzato per chiamare l’API back-end di Laravel. Eseguire il seguente comando sul terminale:

npm install vue vue-router vue-axios --save

Creare migrazione, modello e controller

Creare un modello di categoria, una migrazione e un controller. Esegui il seguente comando per questo:

php artisan make:model Category -mcr

-mcr  questo argomento creerà Model, Migration e Controller sfruttando la sintesi del comando unico.

Ora, apri il file di migrazione della categoria dal database / migrazione e sostituisci il codice nella funzione up () :

public function up()
{
    Schema::create('categories', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('title');
        $table->text('description');
        $table->timestamps();
    });
}

Migrare il database utilizzando il seguente comando:

php artisan migrate

Ora, apri il modello Category.php dall’app/Models  e modifica il codice nel file model Category.php :

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Category extends Model {

   use HasFactory;

   protected $fillable = ['title','description'];

}

?>

Successivamente, apri CategoryController.php e aggiungi il codice nei metodi index, store, update ed delete come segue:

<?php

namespace App\Http\Controllers;

use App\Models\Category;
use Illuminate\Http\Request;

class CategoryController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $categories = Category::all(['id','title','description']);
        return response()->json($categories);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $category = Category::create($request->post());
        return response()->json([
            'message'=>'Category Created Successfully!!',
            'category'=>$category
        ]);
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Category  $category
     * @return \Illuminate\Http\Response
     */
    public function show(Category $category)
    {
        return response()->json($category);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Category  $category
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Category $category)
    {
        $category->fill($request->post())->save();
        return response()->json([
            'message'=>'Category Updated Successfully!!',
            'category'=>$category
        ]);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Category  $category
     * @return \Illuminate\Http\Response
     */
    public function destroy(Category $category)
    {
        $category->delete();
        return response()->json([
            'message'=>'Category Deleted Successfully!!'
        ]);
    }
}

Definire le Routes in web.php

Ora definisci le routes nei file web.php e api.php . Vai alla cartella routes e apri il file web.php e api.php e aggiorna le seguenti routes:

Articoli correlati

routes/web.php

Newsletter sull’Innovazione
Non perderti le notizie più importanti sull'Innovazione. Iscriviti per riceverle via e-mail.
<?php
 
Route::get('{any}', function () {
    return view('app');
})->where('any', '.*');

routes/api.php

<?php
 
Route::resource('category',App\Http\Controllers\CategoryController::class)->only(['index','store','show','update','destroy']);

Crea un’app Vue

In questo passaggio, vai alla directory resource/views, crea il  file app.blade.php  e aggiungi il seguente codice a app.blade.php:

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="csrf-token" value="{{ csrf_token() }}"/>
        <title>Laravel Vue CRUD App</title>
        <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet" type="text/css">
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
        <link href="{{ mix('css/app.css') }}" type="text/css" rel="stylesheet"/>
    </head>
    <body>
        <div id="app">
        </div>
        <script src="{{ mix('js/app.js') }}" type="text/javascript"></script>
    </body>
</html>

Crea componente per l’app Vue

In questo passaggio, vai alla  cartella resource/js, crea la cartella components  e crea i file come segue:

  • View app
  • Welcome.vue
  • Category/List.vue
  • Category/Add.vue
  • Category/Edit.vue

App.vue  è il file principale della nostra app Vue. Definiremo router-view  in quel file. Tutti i percorsi verranno visualizzati nel file App.vue  .

Apri il file Welcome.vue e aggiorna il seguente codice in quel file:

<template>
    <div class="container mt-5">
        <div class="col-12 text-center">
            <h1>Laravel Vuejs CRUD</h1>
        </div>
    </div>
</template>

Apri il file App.vue e aggiorna il codice come segue:

<template>
    <main>
        <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
            <div class="container-fluid">
                <router-link to="/" class="navbar-brand" href="#">Laravel Vue Crud App</router-link>
                <div class="collapse navbar-collapse">
                    <div class="navbar-nav">
                        <router-link exact-active-class="active" to="/" class="nav-item nav-link">Home</router-link>
                        <router-link exact-active-class="active" to="/category" class="nav-item nav-link">Category</router-link>
                    </div>
                </div>
            </div>
        </nav>
        <div class="container mt-5">
            <router-view></router-view>
        </div>
    </main>
</template>
 
<script>
    export default {}
</script>

Quindi, apri resource / js / components / category / List.vue  e aggiungi il seguente codice nel file:

<template>
    <div class="row">
        <div class="col-12 mb-2 text-end">
            <router-link :to='{name:"categoryAdd"}' class="btn btn-primary">Create</router-link>
        </div>
        <div class="col-12">
            <div class="card">
                <div class="card-header">
                    <h4>Category</h4>
                </div>
                <div class="card-body">
                    <div class="table-responsive">
                        <table class="table table-bordered">
                            <thead>
                                <tr>
                                    <th>ID</th>
                                    <th>Title</th>
                                    <th>Description</th>
                                    <th>Actions</th>
                                </tr>
                            </thead>
                            <tbody v-if="categories.length > 0">
                                <tr v-for="(category,key) in categories" :key="key">
                                    <td>{{ category.id }}</td>
                                    <td>{{ category.title }}</td>
                                    <td>{{ category.description }}</td>
                                    <td>
                                        <router-link :to='{name:"categoryEdit",params:{id:category.id}}' class="btn btn-success">Edit</router-link>
                                        <button type="button" @click="deleteCategory(category.id)" class="btn btn-danger">Delete</button>
                                    </td>
                                </tr>
                            </tbody>
                            <tbody v-else>
                                <tr>
                                    <td colspan="4" align="center">No Categories Found.</td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    name:"categories",
    data(){
        return {
            categories:[]
        }
    },
    mounted(){
        this.getCategories()
    },
    methods:{
        async getCategories(){
            await this.axios.get('/api/category').then(response=>{
                this.categories = response.data
            }).catch(error=>{
                console.log(error)
                this.categories = []
            })
        },
        deleteCategory(id){
            if(confirm("Are you sure to delete this category ?")){
                this.axios.delete(`/api/category/${id}`).then(response=>{
                    this.getCategories()
                }).catch(error=>{
                    console.log(error)
                })
            }
        }
    }
}
</script>

Successivamente, apri  resource /js/components/category/Add.vue  e aggiorna il seguente codice nel file:

<template>
    <div class="row">
        <div class="col-12">
            <div class="card">
                <div class="card-header">
                    <h4>Add Category</h4>
                </div>
                <div class="card-body">
                    <form @submit.prevent="create">
                        <div class="row">
                            <div class="col-12 mb-2">
                                <div class="form-group">
                                    <label>Title</label>
                                    <input type="text" class="form-control" v-model="category.title">
                                </div>
                            </div>
                            <div class="col-12 mb-2">
                                <div class="form-group">
                                    <label>Description</label>
                                    <input type="text" class="form-control" v-model="category.description">
                                </div>
                            </div>
                            <div class="col-12">
                                <button type="submit" class="btn btn-primary">Save</button>
                            </div>
                        </div>                        
                    </form>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    name:"add-category",
    data(){
        return {
            category:{
                title:"",
                description:""
            }
        }
    },
    methods:{
        async create(){
            await this.axios.post('/api/category',this.category).then(response=>{
                this.$router.push({name:"categoryList"})
            }).catch(error=>{
                console.log(error)
            })
        }
    }
}
</script>

Successivamente, apri  resource /js/components/category/Edit.vue  e aggiorna il seguente codice nel file:


<template>
    <div class="row">
        <div class="col-12">
            <div class="card">
                <div class="card-header">
                    <h4>Update Category</h4>
                </div>
                <div class="card-body">
                    <form @submit.prevent="update">
                        <div class="row">
                            <div class="col-12 mb-2">
                                <div class="form-group">
                                    <label>Title</label>
                                    <input type="text" class="form-control" v-model="category.title">
                                </div>
                            </div>
                            <div class="col-12 mb-2">
                                <div class="form-group">
                                    <label>Description</label>
                                    <input type="text" class="form-control" v-model="category.description">
                                </div>
                            </div>
                            <div class="col-12">
                                <button type="submit" class="btn btn-primary">Update</button>
                            </div>
                        </div>                        
                    </form>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    name:"update-category",
    data(){
        return {
            category:{
                title:"",
                description:"",
                _method:"patch"
            }
        }
    },
    mounted(){
        this.showCategory()
    },
    methods:{
        async showCategory(){
            await this.axios.get(`/api/category/${this.$route.params.id}`).then(response=>{
                const { title, description } = response.data
                this.category.title = title
                this.category.description = description
            }).catch(error=>{
                console.log(error)
            })
        },
        async update(){
            await this.axios.post(`/api/category/${this.$route.params.id}`,this.category).then(response=>{
                this.$router.push({name:"categoryList"})
            }).catch(error=>{
                console.log(error)
            })
        }
    }
}
</script>

Definisci il percorso per l’app CRUD in Vue Router

Ora, devi definire le Vue routes, e per far questo vai alla  cartella  resource / js , crea il file route.js  e aggiorna il seguente codice nel file:

const Welcome = () => import('./components/Welcome.vue' /* webpackChunkName: "resource/js/components/welcome" */)
const CategoryList = () => import('./components/category/List.vue' /* webpackChunkName: "resource/js/components/category/list" */)
const CategoryCreate = () => import('./components/category/Add.vue' /* webpackChunkName: "resource/js/components/category/add" */)
const CategoryEdit = () => import('./components/category/Edit.vue' /* webpackChunkName: "resource/js/components/category/edit" */)

export const routes = [
    {
        name: 'home',
        path: '/',
        component: Welcome
    },
    {
        name: 'categoryList',
        path: '/category',
        component: CategoryList
    },
    {
        name: 'categoryEdit',
        path: '/category/:id/edit',
        component: CategoryEdit
    },
    {
        name: 'categoryAdd',
        path: '/category/add',
        component: CategoryCreate
    }
]

Qui abbiamo utilizzato componenti di caricamento lentoVue JS gestisce il caricamento dei componenti in modo lazy con i percorsi, quindi sul DOM è possibile caricare i componenti solo quando sono necessari attraverso i percorsi.

Includi le dipendenze Vue.js in app.js

Ora devi aggiungere tutti i percorsi, vue-axios e altre dipendenze.

resource / js / app.js

require('./bootstrap');
import vue from 'vue'
window.Vue = vue;

import App from './components/App.vue';
import VueRouter from 'vue-router';
import VueAxios from 'vue-axios';
import axios from 'axios';
import {routes} from './routes';
 
Vue.use(VueRouter);
Vue.use(VueAxios, axios);
 
const router = new VueRouter({
    mode: 'history',
    routes: routes
});
 
const app = new Vue({
    el: '#app',
    router: router,
    render: h => h(App),
});

Aggiorna webpack.mix.js

webpack.mix.js

const mix = require('laravel-mix');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel applications. By default, we are compiling the CSS
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.js('resources/js/app.js', 'public/js')
    .postCss('resources/css/app.css', 'public/css', [
        //
    ]).vue();

Eseguire il server di sviluppo

Apri il terminale ed esegui questo comando:

npm run watch
php artisan serve

Apri localhost: 8000 nel browser.

BlogInnovazione.it

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

Articoli recenti

Reply rende disponibile MLFRAME Reply un framework basato sull’Intelligenza Artificiale Generativa applicato allo sviluppo e alla condivisione della conoscenza

Reply annuncia il lancio di MLFRAME Reply, un nuovo framework di intelligenza artificiale generativa per basi di conoscenza eterogenee. Ideato…

23 Settembre 2023

Premiate le Startup più Innovative: le 10 finaliste dell’ITALIAN MASTER STARTUP AWARD (IMSA) 2023

Giunge alla sua 17a edizione il Premio IMSA per le giovani startup nate dalla ricerca nell’ambito delle Università e degli…

22 Settembre 2023

I Thought Leader in occasione del Forum per il Premio Zayed per la Sostenibilità evidenziano i percorsi per promuovere il progresso delle persone e del pianeta

Il Premio Zayed per la Sostenibilità è il premio globale per la sostenibilità e l'impegno umanitario degli Emirati Arabi Uniti.…

22 Settembre 2023

Reply ottiene 4 Oracle EMEA Cluster Partner Awards nelle categorie Innovation, Business Impact e Customer Success

Reply, società di consulenza e system integrator a livello globale e Oracle Cloud Managed Service Provider, annuncia di aver ricevuto…

19 Settembre 2023

MasterZ, il Master su Blockchain e WEB 3.0 piu grande d’Europa, lancia una nuova piattaforma dedicata all’apprendimento, alla pratica e al lavoro

MasterZ Blockchain, aumenta il valore per il Master d’ eccellenza WEB 3.0 più grande d' Europa. Il team tutto italiano…

19 Settembre 2023

Lo Zayed Sustainability Prize annuncia 33 finalisti che promuovono iniziative di sostenibilità globale

33 finalisti selezionati tra 5.213 candidature in 163 paesi I finalisti sostengono un'azione climatica incisiva e supportano l'accesso all'energia pulita,…

18 Settembre 2023

Tendenze emergenti e innovazioni nella ricerca biologica: dal banco al letto del paziente

I prodotti biologici si sono evidenziati come una classe farmaceutica innovativa, rivoluzionando il campo della medicina attraverso terapie mirate. A…

17 Settembre 2023

3D Systems semplifica la produzione e promuove l’innovazione continua mediante l’internalizzazione della produzione di piattaforme di stampa aggiuntive

L'internalizzazione delle stampanti per la produzione di metalli e polimeri negli stabilimenti di Riom, Francia e Rock Hill, Carolina del…

17 Settembre 2023

Biognosys presenta innovazioni tecnologiche e progressi scientifici per rendere il proteoma utilizzabile per la ricerca sulle scienze della vita al Congresso mondiale HUPO 2023

L'analisi dei dati senza librerie e potenziata dall'apprendimento automatico con Spectronaut ® 18 offre quantificazione e produttività delle proteine ​​leader del settore…

16 Settembre 2023

Mattermost lancia nuove partnership per favorire una maggiore innovazione e adozione nel settore pubblico

Mattermost presenta un ecosistema ampliato di alleati con un'enfasi sui nuovi casi d'uso del Dipartimento della Difesa per le soluzioni…

16 Settembre 2023