Greetings, fellow developers! Embarking on the journey of crafting a dynamic web application is an exciting endeavor, and what better way to do it than by harnessing the power of Laravel 10 and Vue.js.
In this article, I'll give you a step-by-step guide on creating CRUD operation in laravel 10 with vue 3. Laravel, known for its elegant syntax and powerful features Paired with Vue.js, a progressive JavaScript framework renowned for its simplicity and reactivity.
Also, you can create vue 3 CRUD operation laravel 8, laravel 9, and laravel 10.
So, let's see laravel 10 with vue js crud operation, how to create crud operation using laravel 10 vue.js, crud operation in laravel vue 3, vue 3 crud example, laravel vue 3 crud.
We will install the laravel 10 application using the following command in this step.
composer create-project --prefer-dist laravel/laravel laravel-10-vuejs-crud-operation
Now, we will set up the database configuration in the .env file.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_9_vue_js_crud_operation
DB_USERNAME=root
DB_PASSWORD=root
Run the following command and install the npm package.
npm install
After that, we will install vue, vue-router, and vue-axios. Vue-axios will be used for calling Laravel backend API.
npm install vue vue-router vue-axios --save
Now, let's streamline the process by creating a migration, model, and controller using a single command. The -mcr
command is a convenient shortcut that automates the generation of migration files, model classes, and controllers, all in one go.
php artisan make:model Category -mcr
Migration:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCategoriesTable extends Migration
{
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->text('description');
$table->timestamps();
});
}
public function down()
{
Schema::drop("categories");
}
}
Afterwards, migrate the table to the database using the following command:
php artisan migrate
In this step, we will update the Category.php
model.
app/Models/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'];
}
?>
Now, let's proceed to update the CategoryController.php
file.
app/Http/Controllers/CategoryController.php
<?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!!'
]);
}
}
Now, let's set up routes in both the web.php
and api.php
files. Add the following route declarations to these files:
routes/web.php
<?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']);
In this step, we will generate an app.blade.php
file. To do so, kindly add the following code to this newly created file.
resource/views/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>Building a Laravel 10 Vue.js CRUD Application - Vidvatek</title>
<link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet" type="text/css">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" 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>
In this step, we will create a Vue component within the components
folder located in the resources/js
directory.
- View app
- Welcome.vue
- Category / List.vue
- Category / Add.vue
- Category / Edit.vue
App.vue is the main file of our Vue app. We will define router-view in that file. All the routes will be shown in App.vue file.
Update Welcome.vue file
<template>
<div class="container mt-5">
<div class="col-12 text-center">
<h1>Vidvatek</h1>
<a href="https://vidvatek.com/" target="_blank">Visit For More Awesome Articles</a>
</div>
</div>
</template>
Afterward, open the App.vue
file and update the code as follows:
<template>
<main>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<router-link to="/" class="navbar-brand" href="#"> How to Create Laravel 10 Vue 3 CRUD OPeration - Vidvatek</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>
Update resource/js/components/category/List.vue
<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>
Next, open resources/js/components/category/Add.vue
and update the following code within the 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>
Now, open resource/js/components/category/Edit.vue and update the following code into the 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>
In this step, we will define routes in the routes.js
file.
resource/js/routes.js
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
}
]
Now, we will add routes to the app.js file.
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),
});
Now, let's proceed to update the webpack.mix.js file.
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();
In this step, we will run the Laravel 10 Vue 3 CRUD operation application using the following command:
npm run watch
php artisan serve
You might also like:
- Read Also: Laravel 10 REST API CRUD Operation
- Read Also: How to Play Sounds in React Native
- Read Also: How to Create Autocomplete Search in Vue JS
- Read Also: Laravel 10 AJAX CRUD Operations With Popup Modal