In this tutorial, i am going to engender Laravel and Vue js crud tutorial. We will engender a Single Page Application(SPA) utilizing the Laravel and Vue.js. This tutorial you will learn how to utilize Vue router and v-form package to engender laravel vue js crud.
In Todays, the Most popular JS frameworks are Angular JS and Vue JS. Angular JS and Vue JS are a very utilizer cordial JS Framework and most popular. It provides to manage the whole project or application without a refresh page and puissant jquery validation.
In this post, I going to learn how to engender CRUD(Engender, Read, Update, and Efface) application with pagination utilizing Laravel 6. In this example i integrated "Utilizer Management" with you can do several options like as bellow:
In this single page application vue and laravel crud example, we will optically discern from scratch how we can engender vue laravel crud system. If you don't konw about laravel 7/6 vue js crud, then you are a right place. I will avail you to engender laravel vue js crud.
1. User Listing
2. User Create
3. User Edit
4. User Delete
I will show you how to use JavaScript moment js and how to use Vue filter, Vue progressbar, Vue router to complete this single page application. So let's start our tutorial laravel vue js simple crud.
you can implement crud application from scratch, so no worry if you can implement through bellow simple step. After create successful example, you will find layout as bellow:
Preview: User Table
Preview: Add User Modal
Preview: Error message before submit non-validate data
Preview: Edit modal window
Now let's start laravel vue js crud application tutorial from scratch.
Step 1: Laravel Installation
In first step, If you haven't installed Laravel in your system then you have to run bellow command and get fresh Laravel project.
composer create-project --prefer-dist laravel/laravel VueCRUD
Step 2: Create items table and model
In this step i will use User model and users table to create vue js laravel crup single page application. So paste this below code to your users table.
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->string('type')->default('user');
$table->rememberToken();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('users');
}
}
After create "usres" table you should create Item model for items, so first create file in this path app/User.php and put bellow content in user.php file:
app/User.php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use Notifiable;
protected $guarded = [];
}
Now run migration command after setup your database.
Step 3: Define the API routes
Now, we need to define the API routes inside the routes >> api.php file.
routes/api.php
//Vue js Api Route
Route::apiResources(
[
'user' => 'API\UserController'
]
);
Step 4: Create Controller
To quickly generate an API resource controller that does not include the create
or edit
methods, use the --api
switch when executing the make:controller
command:
php artisan make:controller API/UserController --api
Ok, now we have created new controller as UserController in this path app/Http/Controllers/API/UserController.php. this controller will manage all route method:
Step 5 : Setup Laravel Mix
Now open webpack.mix.js which is located inside your root directory.
webpack.mix.js
mix.js('resources/assets/js/app.js', 'public/js/app.js')
.sass('resources/assets/sass/app.scss', 'public/css/app.css')
.version();
Step 6 : Install Vue dependency and edit configurations
Now, go inside the project folder and install the frontend dependencies using the following command.
npm install
Now run following command, you can visit vue official documentation
npm install vue-router
Now we are going to install vue-progressbar. We will use it when a user created then progressbar will be shown in top of our application. Now run following command, you can visit vue progressbar official documentation
npm install vue-progressbar
Now we have to install moment js in our app to format date like laravel carbon function. You can visit moment js official documentation
npm install moment --save
Now we have to install v-form for client side validation. Read their documentation to learn more how to use it and how v-form works.
npm i axios vform
Now last is sweet alert 2. Now run below command to install it. You can visit sweet alert 2 official documentation. Now run command to compile our all javascript file.
npm install watch
Now create folder and file like below image.
Step 7: Setup js file
resources/assets/js/app.js
require('./bootstrap');
window.Vue = require('vue');
//Import Vue Filter
require('./filter');
//Import progressbar
require('./progressbar');
//Setup custom events
require('./customEvents');
//Import View Router
import VueRouter from 'vue-router'
Vue.use(VueRouter)
//Import Sweetalert2
import Swal from 'sweetalert2'
window.Swal = Swal
const Toast = Swal.mixin({
toast: true,
position: 'top-end',
showConfirmButton: false,
timer: 3000,
timerProgressBar: true,
onOpen: (toast) => {
toast.addEventListener('mouseenter', Swal.stopTimer)
toast.addEventListener('mouseleave', Swal.resumeTimer)
}
})
window.Toast = Toast
//Import v-from
import { Form, HasError, AlertError } from 'vform'
window.Form = Form;
Vue.component(HasError.name, HasError)
Vue.component(AlertError.name, AlertError)
//Routes
import { routes } from './routes';
//Register Routes
const router = new VueRouter({
routes,
mode: 'hash',
})
//Vue.component('example-component', require('./components/ExampleComponent.vue').default);
const app = new Vue({
el: '#app',
router
});
resources/assets/js/customEvents.js
This is our custom events generator code. You can see its documentation to know better.
//Setup our custom events in vue
let Fire = new Vue()
window.Fire = Fire;
resources/assets/js/filter.js
//Vue Filter to make first letter Capital
Vue.filter("strToUpper", function(text) {
return text.charAt(0).toUpperCase() + text.slice(1);
});
//Vue moment js to show human readable date
import moment from "moment"; //Import Moment
Vue.filter("formatDate", function(date) {
return moment(date).format('MMMM Do YYYY');
});
resources/assets/js/progressbar.js
import VueProgressBar from 'vue-progressbar';
Vue.use(VueProgressBar, {
color: 'rgb(143, 255, 199)',
failedColor: 'red',
height: '4px',
transition: {
speed: '0.4s',
opacity: '0.6s',
termination: 300
},
})
resources/assets/js/routes.js
import Dashboard from './components/admin/DashboardComponent.vue'
import Profile from './components/admin/ProfileComponent.vue'
import User from './components/admin/UserComponent.vue'
export const routes = [
{
path:'/dashboard',
component:Dashboard
},
{
path:'/profile',
component:Profile
},
{
path:'/users',
component:User
},
];
Step 8 : Setup Controller
App\Http\Controllers\API\UserController.php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\User;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function index()
{
return User::latest()->get();
}
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required',
'email' => 'required',
'type' => 'required',
]);
return User::create([
'name' => $request['name'],
'email' => $request['email'],
'password' => \Hash::make($request['password']),
'type' => $request['type'],
]);
}
public function show($id)
{
//
}
public function update(Request $request, $id)
{
$this->validate($request, [
'name' => 'required',
'email' => 'required',
'type' => 'required',
]);
$user = User::findOrFail($id);
$user->update($request->all());
}
public function destroy($id)
{
$user = User::findOrFail($id);
$user->delete();
return response()->json([
'message' => 'User deleted successfully'
]);
}
}
Step 9: Create Blade File
In this step we have to create only one blade file that will manage create, update and delete operation of items module with vue js.In this file i added jquery, bootstrap js and css, vue.js, vue-resource.min.js, toastr js and css for notification in this blade file.
resources/views/master.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Vue js App</title>
<meta name="csrf-token" content="{{ csrf_token() }}">
<link rel="stylesheet" href="{{ mix('css/app.css') }}">
</head>
<body class="hold-transition sidebar-mini">
<div class="wrapper" id="app">
<aside class="main-sidebar sidebar-dark-primary elevation-4">
<div class="sidebar">
<nav class="mt-2">
<ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
<li class="nav-item">
<router-link to="/dashboard" class="nav-link">
<i class="nav-icon fas fa-tachometer-alt blue"></i>
<p>
Dashboard
</p>
</router-link>
</li>
<li class="nav-item has-treeview">
<a href="#" class="nav-link">
<i class="nav-icon fa fa-cog green"></i>
<p>
Management
<i class="right fa fa-angle-left"></i>
</p>
</a>
<ul class="nav nav-treeview">
<li class="nav-item">
<router-link to="/users" class="nav-link">
<i class="fas fa-users nav-icon"></i>
<p>Users</p>
</router-link>
</li>
</ul>
</li>
<li class="nav-item">
<router-link to="/profile" class="nav-link">
<i class="nav-icon fas fa-user orange"></i>
<p>
Profile
</p>
</router-link>
</li>
</ul>
</nav>
</div>
</aside>
<div class="content-wrapper">
<div class="content">
<div class="container-fluid">
<router-view></router-view>
<vue-progress-bar></vue-progress-bar>
</div>
</div>
</div>
</div>
<script src="{{ mix('js/app.js') }}"></script>
</body>
</html>
resources/assets/js/components/admin/UserComponent.vue
<template>
<div class="container">
<div class="row mt-5">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">Users Table</h3>
<div class="card-tools">
<button class="btn btn-success" data-toggle="modal" data-target="#addNew" @click="openModalWindow">Add New <i class="fas fa-user-plus fa-fw"></i></button>
</div>
</div>
<div class="card-body table-responsive p-0">
<table class="table table-hover">
<tbody>
<tr>
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Type</th>
<th>Registered At</th>
<th>Modify</th>
</tr>
<tr v-for="user in users" :key="user.id">
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
<td>{{ user.email }}</td>
<td>{{ user.type | strToUpper}}</td>
<td>{{ user.created_at | formatDate}}</td>
<td>
<a href="#" data-id="user.id" @click="editModalWindow(user)">
<i class="fa fa-edit blue"></i>
</a>
|
<a href="#" @click="deleteUser(user.id)">
<i class="fa fa-trash red"></i>
</a>
</td>
</tr>
</tbody>
</table>
</div>
<div class="card-footer">
</div>
</div>
</div>
</div>
<div class="modal fade" id="addNew" tabindex="-1" role="dialog" aria-labelledby="addNewLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 v-show="!editMode" class="modal-title" id="addNewLabel">Add New User</h5>
<h5 v-show="editMode" class="modal-title" id="addNewLabel">Update User</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<form @submit.prevent="editMode ? updateUser() : createUser()">
<div class="modal-body">
<div class="form-group">
<input v-model="form.name" type="text" name="name"
placeholder="Name"
class="form-control" :class="{ 'is-invalid': form.errors.has('name') }">
<has-error :form="form" field="name"></has-error>
</div>
<div class="form-group">
<input v-model="form.email" type="email" name="email"
placeholder="Email Address"
class="form-control" :class="{ 'is-invalid': form.errors.has('email') }">
<has-error :form="form" field="email"></has-error>
</div>
<div class="form-group">
<input v-model="form.password" type="password" name="password" id="password" placeholder="Enter password"
class="form-control" :class="{ 'is-invalid': form.errors.has('password') }">
<has-error :form="form" field="password"></has-error>
</div>
<div class="form-group">
<select name="type" v-model="form.type" id="type" class="form-control" :class="{ 'is-invalid': form.errors.has('type') }">
<option value="">Select User Role</option>
<option value="admin">Admin</option>
<option value="user">Standard User</option>
<option value="author">Author</option>
</select>
<has-error :form="form" field="type"></has-error>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
<button v-show="editMode" type="submit" class="btn btn-primary">Update</button>
<button v-show="!editMode" type="submit" class="btn btn-primary">Create</button>
</div>
</form>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
editMode: false,
users: {},
form: new Form({
id: '',
name : '',
email: '',
password: '',
type: '',
})
}
},
methods: {
editModalWindow(user){
this.form.clear();
this.editMode = true
this.form.reset();
$('#addNew').modal('show');
this.form.fill(user)
},
updateUser(){
this.form.put('api/user/'+this.form.id)
.then(()=>{
Toast.fire({
icon: 'success',
title: 'User updated successfully'
})
Fire.$emit('AfterCreatedUserLoadIt');
$('#addNew').modal('hide');
})
.catch(()=>{
console.log("Error.....")
})
},
openModalWindow(){
this.editMode = false
this.form.reset();
$('#addNew').modal('show');
},
loadUsers() {
axios.get("api/user").then( data => (this.users = data.data));
//pick data from controller and push it into users object
},
createUser(){
this.$Progress.start()
this.form.post('api/user')
.then(() => {
Fire.$emit('AfterCreatedUserLoadIt'); //custom events
Toast.fire({
icon: 'success',
title: 'User created successfully'
})
this.$Progress.finish()
$('#addNew').modal('hide');
})
.catch(() => {
console.log("Error......")
})
//this.loadUsers();
},
deleteUser(id) {
Swal.fire({
title: 'Are you sure?',
text: "You won't be able to revert this!",
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Yes, delete it!'
}).then((result) => {
if (result.value) {
//Send Request to server
this.form.delete('api/user/'+id)
.then((response)=> {
Swal.fire(
'Deleted!',
'User deleted successfully',
'success'
)
this.loadUsers();
}).catch(() => {
Swal.fire({
icon: 'error',
title: 'Oops...',
text: 'Something went wrong!',
footer: '<a href>Why do I have this issue?</a>'
})
})
}
})
}
},
created() {
this.loadUsers();
Fire.$on('AfterCreatedUserLoadIt',()=>{ //custom events fire on
this.loadUsers();
});
}
}
</script>
i hope you like this article.