Laravel Vue Js CRUD SPA Notifikasi Hapus Data
Laravel Vue Js CRUD SPA Notifikasi Hapus Data, Photo: Jogjatech.com

Halo Laravel lovers, jika saat ini Anda sedang membutuhkan tutorial membuat crud laravel combine vue js, maka menemukan halaman ini adalah bacaan yang tepat, terutama bagi para pemula atau biasa disebut beginners. Pada tutorial ini juga disertai fitur sweet alert pada operasi update dan delete data.

Setelah sebelumnya telah membahas pembahasan step by step cara membagun aplikasi pertama dengan Laravel 7, maka pada tutorial ini saya akan mencoba mengupas perpaduan Laravel dan VueJs serta Vue Router pada judul Laravel Tutorial: Step by Step Laravel dan Vue Js CRUD SPA (Single Page Application).

Dan tutorial kali ini, saya akan membahas bagaimana melakukan operasi CRUD (Create, Read, Update dan Delete) dengan Laravel dan Vue Js. CRUD adalah operasi data dasar dan menjadi salah satu hal pertama yang harus dipelajari sebagai pengembang aplikasi Laravel. Vue Js merupakan bagan dari paket laravel/ui yang tersedia pada Laravel 6 dan versi yang terbaru sekarang yakni Laravel 7. Vue menjadi pilihan tepat untuk membuat antarmuka pengguna yang dinamis untuk operasi CRUD.

Berikut adalah Step by Step Laravel dan Vue Js CRUD SPA.

Install npm dependencies

Untuk install dependecies buka jendela Terminal/ Commmand Prompt kemudian ketik perintah seperti berikut.

npm install

Setelah selesai. Selanjutnya ketikkan dan jalankan perintah npm run watch di terminal seperti berikut.

npm run watch

Selanjutnya yang kita perlukan adalah meng-install beberapa dependencies tambahan seperti vue-router dan vue-axios.

Install Vue Axios, Vue Router dan Vue Sweet Alert2 di Laravel

Vue-router digunakan untuk mengatur SPA (single page application) route pada aplikasi, dan vue-axios digunakan untuk meng-handle rest api.

Untuk install dependencies dengan cara ketik perintah npm install vue-router vue-axios seperti berikut.

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

Membuat File Pendukung CRUD Laravel dan Vue Js

Project Laravel dan Vue Js CRUD SPA
Project Laravel dan Vue Js CRUD SPA

Membuat Migration, Model and Controller

Disini kita akan membuat table migration, model, dan controller. Dimana didalam controller memuat method add, read, update, dan delete, maka kita bisa menjalankan perintah artisan berikut

php artisan make:model Buku -mcr

Fungsi artisan diatas jika kita jalankan pada jendela Terminal/ Command Prompt maka akan sekaligus menciptakan tiga file seperti, file migration “create_bukus_table.php” pada folder “database>migrations”, dan menciptakan file model “Buku.php” pada folder “app”, serta menciptakan file controller “BukuController.php” pada folder “app\Http\Controllers”.

Mendefinisikan Fungsi-Fungsi Pada Controller

Buka file controller “BukuController.php” yang telah kita buat pada folder “app\Http\Controllers\BukuController.php”, lalu modifikasi dan lengkapi seperti berikut.

BukuController.php

<?php

namespace App\Http\Controllers;

use App\Buku;
use Illuminate\Http\Request;

class BukuController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$buku = Buku::all()->toArray();
return array_reverse($buku);
}


/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$buku = new Buku([
'name' => $request->input('name'),
'author' => $request->input('author')
]);
$buku->save();

return response()->json('Data berhasil disimpan');
}

/**
* Show the form for editing the specified resource.
*
* @param \App\Buku $buku
* @return \Illuminate\Http\Response
*/
public function getBuku($id)
{
$buku = Buku::find($id);
return response()->json($buku);
}

/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Buku $buku
* @return \Illuminate\Http\Response
*/
public function updateBuku(Request $request, $id)
{
$book = Buku::find($id);
$book->update($request->all());

return response()->json('Data berhasil diupdate');
}

/**
* Remove the specified resource from storage.
*
* @param \App\Buku $buku
* @return \Illuminate\Http\Response
*/
public function deleteBuku($id)
{
$buku = Buku::find($id);
$buku->delete();

return response()->json('Data berhasil dihapus');
}
}

Membuat Database Migration

Buka file migration yang telah kita buat pada folder “database/migrations/…create_bukus_table.php”, lalu pada function up() tambahkan kode berikut.

create_bukus_table.php

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateBukusTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('buku', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('author');
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('bukus');
}
}

Melengkapi File Model

Buka file model yang telah kita buat pada folder “app/Buku.php”, lalu ketikkan kode seperti berikut.

Buku.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Buku extends Model
{
protected $table = "buku";
protected $fillable = ['name', 'author'];
}

Membuat Data Palsu Dengan Laravel Seeder dan Faker

Menyiapkan data fake atau data palsu adalah langkah yang tepat ketika kita sedang mendevelop aplikasi. Mengisi database tabel buku dengan data fake atau data palsu dapat kita lakukan dengan fitur database seeder atau database seeding di laravel.

Jika sebelumnya Anda belum meng-install Faker pada project Anda, maka Anda dapat meng-installnya dengan menjalankan perintah composer berikut.

composer require fzaninotto/faker

Kemudian buatlah file database seeder seperti contoh berikut.

php artisan make:seeder BukuSeeder

Maka, Laravel akan membuat sebuah file seeder “BukuSeeder.php” pada folder “database/seeds/BukuSeeder.php”. Buka file seeder yang telah dibuat dan ketikkan kode berikut pada function run().

BukuSeeder.php

<?php

use Illuminate\Database\Seeder;
use Faker\Factory as Faker;

class BukuSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$faker = Faker::create('id_JP');

for($i=1; $i <= 10; $i++){
DB::table('buku')->insert([
'name' => $faker->sentence(3),
'author' => $faker->name
]);
}
}
}

Kemudian jalankan database seeder dan laravel faker dengan perintah berikut.

php artisan db:seed --class=BukuSeeder

Maka faker akan membuatkan data fake sebanyak perintah perulangan yang kita ketikkan diatas.

Memodifikasi Route Web dan Api Pada Laravel

Langkah selanjutnya adalah menambhakan beberapa kode routes web dan routes API, buka file web.php pada folder “routes” dan tambahkan kode berikut.

web.php

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
return view('welcome');
});

Auth::routes();

Route::get('/home', 'HomeController@index')->name('home');
Route::get('/{any}', function () {
return view('app');
})->where('any', '.*');

Dan buka routes API lalu tambahkan kode berikut.

api.php

<?php

use Illuminate\Http\Request;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});

Route::get('/buku', 'BukuController@index');
Route::post('/buku/store', 'BukuController@store');
Route::get('/buku/edit/{id}', 'BukuController@getBuku');
Route::put('/buku/update/{id}', 'BukuController@updateBuku');
Route::delete('/buku/delete/{id}', 'BukuController@deleteBuku');

Membuat Vue App

Buatlah sebuah file view app.blade.php pada folder “resources/views/app.blade.php”, lalu rubahlah kode sehingga tampak seperti berikut.

app.blade.php

<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">

<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">

<title>Laravel Vue Js Jogjatech.com</title>

<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
<div id="app"></div>

<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>

Menambahkan Vue Components

Disini saya menambahkan 3 vue components pada folder “resources/views/js/components”, lalu saya menambahkan 3 file berikut.

App.vue
BukuAll.vue
BukuCreate.vue
BukuEdit.vue

File BukuAll.vue saya gunakan untuk menmpilkan data-data dari database. File BukuCreate.vue saya jadikan form ketika ingin menambah data. Dan file BukuEdit.vue saya gunakan untuk menampilkan form edit data. Sedangkan file App.vue saya gunakan sebagai template dan router view-nya.

Selanjutnya adalah kita melengkapi file-file yang telah kita buat, seperti berikut.

app.js

require('./bootstrap');

window.Vue = require('vue');

import VueRouter from 'vue-router';
import VueAxios from 'vue-axios';
import axios from 'axios';
import App from './components/App.vue';
import VueSweetalert2 from 'vue-sweetalert2';
// If you don't need the styles, do not connect
import 'sweetalert2/dist/sweetalert2.min.css';

Vue.use(VueRouter);
Vue.use(VueSweetalert2);
Vue.use(VueAxios, axios);
Vue.component('pagination', require('laravel-vue-pagination'));

import BukuAll from './components/BukuAll.vue';
import BukuCreate from './components/BukuCreate.vue';
import BukuEdit from './components/BukuEdit.vue';

const routes = [
{
name: 'home',
path: '/home',
},
{
name: 'buku',
path: '/buku',
component: BukuAll
},
{
name: 'create',
path: '/buku/create',
component: BukuCreate
},
{
name: 'edit',
path: '/buku/edit/:id',
component: BukuEdit
}
];

const router = new VueRouter({ mode: 'history', routes: routes });
const app = new Vue(Vue.util.extend({ router }, App)).$mount('#app');

App.vue.

<template>
<div class="page">
<nav class='navbar navbar-expand-lg navbar-dark bg-dark'>
<div class='container'>
<router-link :to="{ name: 'buku' }" class="navbar-brand">Laravel Vue Js Jogjatech.com</router-link>
</div>
<div class="collapse navbar-collapse">
<div class="navbar-nav">
<router-link to="/" class="nav-item nav-link">Home</router-link>
<router-link to="/buku" class="nav-item nav-link">Buku</router-link>
</div>
</div>
</nav>
<router-view></router-view>
</div>
</template>
<script>
export default {}
</script>

BukuAll.vue

<template>
<div class='container py-2'>
<div class='row justify-content-center'>
<div class='col-md-12'>
<div class='card'>
<div class='card-header'>Daftar Nama Buku</div>
<div class='card-body'>
<router-link :to="{ name: 'create' }" class="btn btn-primary">Tambah</router-link>
<br/>
<br/>
<div class="table-responsive">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th width="50" class="text-center">No</th>
<th>Title</th>
<th>Author</th>
<th width="200" class="text-center">Action</th>
</tr>
</thead>
<tbody>
<tr v-for="(buku, all) in buku.data" :key="buku.id">
<td width="50" class="text-center">{{ all + 1 }}</td>
<td>{{ buku.name }}</td>
<td>{{ buku.author }}</td>
<td width="200" class="text-center">
<div class="btn-group">
<router-link :to="{name: 'edit', params: { id: buku.id }}" class="btn btn-xs btn-success">Edit</router-link>
<button class="btn btn-xs btn-danger" @click = "hapusBuku(buku.id)">Hapus</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<pagination :data="buku" @pagination-change-page="getResult"></pagination>
</div>
</div>
</div>
</div>
</div>
</template>

<script>
export default {
data() {
return {
buku: {}
}
},
/*
created() {
let uri = 'api/buku';
this.axios.get(uri).then(response => {
this.buku = response.data;
});
},
*/
created() {
this.getResult();
},
methods: {
getResult(page){
let uri = 'api/buku?page=' + page;
this.axios.get(uri).then(response => {
return response.data;
}).then(data => {
this.buku = data;
});
},
hapusBuku(id)
{
this.$swal.fire({
title: 'Yakin menghapus data?',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Ya Hapus',
cancelButtonText: 'Batal'
}).then((result) => {
if (result.value) {
this.$swal.fire({
title: 'Success!',
text: 'Data sukses dihapus',
icon: 'success',
timer: 1000
});
let uri = `api/buku/delete/${id}`;
this.axios.delete(uri).then(response => {
//this.buku.splice(this.buku.indexOf(id), 1);
let i = this.buku.map(buku => buku.id).indexOf(id); // find index of your object
this.buku.splice(i, 1)
});
}
})
}
}
}
</script>

BukuCreate.vue

<template>
<div class='container py-2'>
<div class='row justify-content-center'>
<div class='col-md-8'>
<div class='card'>
<div class='card-header'>Form Data</div>
<div class='card-body'>
<form @submit.prevent="BukuCreate">
<div class='form-group'>
<label htmlFor='title'>Title</label>
<input type="text" class="form-control" id="name" v-model="buku.name">
</div>
<div class='form-group'>
<label htmlFor='content'>Author</label>
<input type="text" class="form-control" id="author" v-model="buku.author">
</div>
<div class='form-group'>
<router-link :to="{ name: 'buku' }" class="btn btn-secondary">Back</router-link>
&nbsp;
&nbsp;
<button class='btn btn-primary'>Simpan</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</template>

<script>
export default {
data() {
return {
buku: {},
name: null,
author: null,
}
},
methods: {
BukuCreate() {
let uri = '/api/buku/store';
this.axios.post(uri, this.buku).then((response) => {
this.$router.push({name: 'buku'});
});

}
}
}
</script>

BukuEdit.vue

<template>
<div class='container py-2'>
<div class='row justify-content-center'>
<div class='col-md-8'>
<div class='card'>
<div class='card-header'>Form Data</div>
<div class='card-body'>
<form @submit.prevent="UpdateBuku">
<div class='form-group'>
<label htmlFor='title'>Title</label>
<input type="text" class="form-control" id="name" v-model="buku.name">
</div>
<div class='form-group'>
<label htmlFor='content'>Author</label>
<input type="text" class="form-control" id="author" v-model="buku.author">
</div>
<div class='form-group'>
<router-link :to="{ name: 'buku' }" class="btn btn-secondary">Back</router-link>
&nbsp;
&nbsp;
<button class='btn btn-primary'>Update</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</template>

<script>
export default {
data() {
return {
buku: {}
}
},
created() {
let uri = `/api/buku/edit/${this.$route.params.id}`;
this.axios.get(uri).then((response) => {
this.buku = response.data;
console.log(response.data);
});
},
methods: {
UpdateBuku() {
this.$swal.fire({
title: 'Success',
text: "Data berhasil diupdate",
icon: 'success',
timer: 1000
});
let uri = `/api/buku/update/${this.$route.params.id}`;
this.axios.put(uri, this.buku).then((response) => {
this.$router.push({name: 'buku'});
});
}
}
}
</script>

Compiling dan Testing Laravel 7 dan Vue Js

Setelah melengkapi kebutuhan membuat CRUD laravel dan Vue Js diatas, maka langkah selanjutnya adalah melakukan compiling pekerjaan. Jalankan perintah berikut pada jendela Terminal/ Command Prompt project.

npm run dev

Selanjutnya adalah kita melakukan testing, jika berjalan dengan baik maka akan ditampilkan halaman seperti berikut disaat kita jalankan project dengan alamat url localhost:8000/buku.

Laravel dan Vue Js CRUD SPA
Laravel Vue Js CRUD SPA

Kesimpulan

Dengan telah menyelesaikan tutorial Step by Step Tutorial Laravel dan Vue Js Membuat CRUD SPA (Single Page Application), maka kita telah berhasil membuat aplikasi CRUD sederhana dengan memanfaatkan Laravel dan Vue Js.

Jika terjadi error atau kurang tepat pada pengetikan kode, harap berikan komentar dibawah, terimakasih…

LEAVE A REPLY

Please enter your comment!
Please enter your name here