Articles

Creació d'una aplicació CRUD amb Laravel i Vue.js

En aquest tutorial veiem junts com escriure el codi per a una aplicació CRUD d'exemple, amb Laravel i Vue.js.

La Aplicació d'una sola pàgina ens permetrà completar un cicle bàsic d'operacions a la base de dades: crear, llegir, actualitzar i eliminar amb Vue.js , Vue Router i Marc Laravel .

Avui en dia, els frameworks JS més populars són Angular JS i Vue JS. Angular JS i Vue JS són frameworks JS molt fàcils d'utilitzar i més populars. Proporciona la gestió de tot el projecte o aplicació sense actualitzar la pàgina i una potent validació de jquery.

Vue ve empaquetat amb Laravel (juntament amb Laravel Mix , una excel·lent eina de creació basada en paquet web ) i permet als desenvolupadors començar a crear aplicacions complexes d'una sola pàgina sense preocupar-se pels transpiladors, paquets de codi, mapes font o altres aspectes "bruts" del desenvolupament de frontend modern.

Requisits del servidor

7.4 Php

Laravel 8.x

MySQL

Instal·leu el projecte Laravel

Primer, obriu Terminal i executeu l'ordre següent per crear un nou projecte laravel:

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

o, si heu instal·lat Laravel Installer com a dependència global del compositor:

laravel new crud-spa

Configura els detalls de la base de dades:

Després de la instal·lació, aneu al directori arrel del projecte, obriu el fitxer .env i configureu els detalls de la base de dades de la següent manera:

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

Instal·leu dependències de NPM

Executeu l'ordre següent per instal·lar les dependències del front-end:

npm install

A continuació, instal·leu vue ,  vue-router  e vista-axios . Vue-axios s'utilitzarà per trucar a l'API de fons de Laravel. Executeu l'ordre següent al terminal:

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

Crea migració, model i controlador

Creeu un model de categoria, una migració i un controlador. Executeu l'ordre següent per a això:

php artisan make:model Category -mcr

-mcr  aquest tema crearà Model, Migració i Controlador aprofitant la síntesi d'ordres únics.

Ara, obriu el fitxer de migració de categories des de base de dades / migració i substituïu el codi a la funció amunt () :

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

Migreu la base de dades amb l'ordre següent:

php artisan migrate

Ara, obriu la plantilla Category.php des deapp/Models  i editeu el codi del fitxer model Categoria.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'];

}

?>

A continuació, obre CategoriaController.php i afegiu el codi a l'índex, emmagatzemeu, actualitzeu i suprimiu els mètodes de la següent manera:

<?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!!'
        ]);
    }
}

Defiacabar les Rutes a web.php

Ara definisi le routes en fitxers web.php e api.php . Aneu a la carpeta routes i obriu el fitxer web.php i api.php i actualitzeu el següent routes:

routes/web.php

Butlletí d'innovació
No et perdis les notícies més importants sobre innovació. Registra't per rebre'ls per correu electrònic.
<?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']);

Creeu una aplicació Vue

En aquest pas, aneu al directori recursos/visites, creeu el fitxer app.blade.php  i afegiu el codi següent 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 un component per a l'aplicació Vue

En aquest pas, aneu a la carpeta resource/js, creeu la carpeta components  i creeu els fitxers de la següent manera:

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

App.vue  és el fitxer principal de la nostra aplicació Vue. Defiacabarem vista de l'encaminador  en aquest fitxer. Tots els camins apareixeran al fitxer App.vue  .

Obriu el fitxer Welcome.vue i actualitzeu el codi següent en aquest fitxer:

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

Obriu el fitxer App.vue i actualitzeu el codi de la següent manera:

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

Aleshores, obre resource / js / components / category / List.vue  i afegiu el codi següent al fitxer:

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

A continuació, obre  resource /js/components/category/Add.vue  i actualitzeu el codi següent al fitxer:

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

A continuació, obre  resource /js/components/category/Edit.vue  i actualitzeu el codi següent al fitxer:


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

DefiAcabeu el camí de l'aplicació CRUD a Vue Router

Ara, has de fer-ho defiacabar-los Vue routes, i per fer-ho aneu a la carpeta  resource / js , creeu el fitxer route.js  i actualitzeu el codi següent al fitxer:

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
    }
]

Aquí hem utilitzat components càrrega lentavista JS gestiona la càrrega de components d'una manera lazy amb camins, de manera que al DOM només podeu carregar components quan siguin necessaris a través de camins.

Inclou dependències de Vue.js a app.js

Ara cal afegir tots els camins, vue-axios i altres dependències.

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),
});

Actualitza 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();

Executeu el servidor de desenvolupament

Obriu el terminal i executeu aquesta comanda:

npm run watch
php artisan serve

Obres host local: 8000 al navegador.

BlogInnovazione.it

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

El regulador antimonopoli del Regne Unit aixeca l'alarma de BigTech sobre GenAI

La CMA del Regne Unit ha emès una advertència sobre el comportament de Big Tech al mercat de la intel·ligència artificial. Allà…

18 2024 abril

Casa Green: revolució energètica per a un futur sostenible a Itàlia

El Decret "Case Green", formulat per la Unió Europea per millorar l'eficiència energètica dels edificis, ha conclòs el seu procés legislatiu amb...

18 2024 abril

Comerç electrònic a Itàlia al +27% segons el nou Informe de Casaleggio Associati

Presentació de l'informe anual de Casaleggio Associati sobre comerç electrònic a Itàlia. Informe titulat “AI-Commerce: les fronteres del comerç electrònic amb intel·ligència artificial”.…

17 2024 abril

Idea brillant: Bandalux presenta Airpure®, la cortina que purifica l'aire

Fruit de la innovació tecnològica constant i del compromís amb el medi ambient i el benestar de les persones. Bandalux presenta Airpure®, una tenda de campanya...

12 2024 abril