Tutorial Membuat Fitur Favorite Seperti Instagram dengan Laravel 8 dan VueJS

Tutorial Membuat Fitur Favorite Seperti Instagram dengan Laravel 8 dan VueJS

Admin
Admin・ 10 Juni 2021
16 min read ・ 3698 views
Series: Laravel VueJS

Fitur Favorite Laravel VueJS - Fitur Favorite atau Save atau Bookmarks sering kali kita temukan di web-web besar seperti twitter, instagram, facebook dan lain-lain. Fitur ini berfungsi untuk menyimpan konten untuk dibaca atau dilihat lagi di lain waktu.

Di artikel ini, saya akan sharing bagaimana cara membuat fitur favorite seperti instagram dengan menggunakan laravel versi 8 dan Vue JS. Simak dan ikuti setiap langkah-langkahnya di bawah ini.

Mulai Koding Membuat Fitur Favorite

Baiklah, mari kita langsung ke koding diawali dengan menginstall laravel project versi terbaru.

Install Laravel

composer create-project laravel/laravel laravel-vuejs-favorite-feature
cd laravel-vuejs-favorite-feature

Langkah pertama yang akan kita lakukan yaitu menginstall laravel versi terbaru. Jalankan perintah di atas secara berurutan untuk menginstall laravel versi terbaru dan masuk ke direktori project saat proses installasi sudah selesai. Disini saya akan mencontohkan dengan menginstall laravel 8 yang akan saya beri nama laravel-vuejs-favorite-feature.

Install Laravel UI

composer require laravel/ui
php artisan ui bootstrap --auth
npm install && npm run dev

Kita perlu membuat sistem authentication pada project percobaan ini. Disini saya akan menggunakan laravel ui package untuk membuat auth scaffolding. Jalankan perintah-perintah seperti di atas secara berurutan untuk membuat auth menggunakan laravel ui package.

Agar nantinya saat register berhasil, user di arahkan ke tampilan root, kita akan mengubah sedikit kode di App/Http/Controllers/Auth/RegisterController.php. Cari kode seperti di bawah ini.

protected $redirectTo = RouteServiceProvider::HOME;

Ubah menjadi

protected $redirectTo = '/';

Menyiapkan View

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css">

Oke. Sebelum lanjut lebih jauh lagi, mari kita siapkan view terlebih dahulu. Disini nanti kita akan menampilkan bookmarks icon dari bootstrap icon, untuk itu di file layouuts/app.blade.php kita akan menggunakan CDN bootstrap icon. Silahkan buka file layouts/app.blade.php, lalu tambahkan sebaris kode di atas sebelum tag </head>.

@extends('layouts.app')
@section('content')
<div class="container">
    <div class="text-center mb-3">
        <h3>Create Favorite Features with Laravel 8 and VueJS</h3>
    </div>
    <div class="card mb-3">
        <div class="card-header">
            2 days ago
        </div>
        <div class="card-body">
            <h5 class="card-title">Special title treatment</h5>
            <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
        </div>
        <div class="card-footer text-muted">
            <i class="bi bi-bookmark" style="font-size: 1.5em;"></i>
        </div>
    </div>
    <div class="card mb-3">
        <div class="card-header">
            2 days ago
        </div>
        <div class="card-body">
            <h5 class="card-title">Special title treatment</h5>
            <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
        </div>
        <div class="card-footer text-muted">
            <i class="bi bi-bookmark" style="font-size: 1.5em;"></i>
        </div>
    </div>
    <div class="card mb-3">
        <div class="card-header">
            2 days ago
        </div>
        <div class="card-body">
            <h5 class="card-title">Special title treatment</h5>
            <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
        </div>
        <div class="card-footer text-muted">
            <i class="bi bi-bookmark" style="font-size: 1.5em;"></i>
        </div>
    </div>
</div>
@endsection

Kemudian kita akan mengubah tampilan root project kita dengan menggunakan card dari bootstrap. Silahkan buka file welcome.blade.php, kemudian ganti semua kode yang ada di file tersebut dengan kode di atas.

Membuat Database

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel-vue-favorite-feature
DB_USERNAME=root
DB_PASSWORD=

Kita perlu membuat database baru untuk menampung data-data seperti user, post dan favorite. Karena disini saya memakai XAMPP sebagai local server saya, maka saya akan membuat database di phpMyAdmin dengan nama laravel-vue-favorite-feature. Jika sudah selesai membuat database, jangan lupa untuk menyesuaikan database configuration di file .env seperti pada contoh di atas.

Membuat File Model & Migration

php artisan make:model Post -m
php artisan make:model Favorite -m

Kemudian kita perlu membuat file model dan migration untuk Post dan Favorite. Silahkan jalankan perintah-perintah di atas secara berurutan di terminal. Dengan perintah-perintah tersebut, kita akan membuat model file Post dan Favorite dan juga membuat migration file untuk post_table dan favorite_table.

<?php

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

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->integer('user_id')->unsigned();
            $table->string('title');
            $table->text('body');
            $table->timestamps();
        });
    }

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

Setelah selesai menjalankan perintah-perintah pada langkah sebelumnya, sekarang kita akan mengatur field-field apa saja yang akan dibuat di masing-masing table posts dan favorites. Pertama, kita akan mengatur pada file database/migrations/ [timestamp] _create_posts_table.php terlebih dahulu, sesuaikan kode yang ada dengan kode di atas. Di table posts nantinya, kita akan membuat field user_id, title dan body.

<?php

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

class CreateFavoritesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('favorites', function (Blueprint $table) {
            $table->id();
            $table->integer('user_id')->unsigned();
            $table->integer('post_id')->unsigned();
            $table->timestamps();
        });
    }

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

Yang kedua, kita akan membuat field user_id dan post_id di table favorites. Buka file database/migrations/ [timestamp] _create_favorites_table.php, kemudian sesuaikan kode yang ada dengan kode seperti di atas. Kemudian jika sudah, jalankan perintah php artisan migrate di terminal.

Membuat Data Dummy dengan Factory

php artisan make:factory PostFactory --model=Post

Ok, setelah membuat table di database, sekarang kita akan membuat data dummy untuk mengisi data pada masing-masing table users dan posts. Yang pertama kita akan membuat Postfactory file terlebih dahulu. Jalankan perintah di atas pada terminal untuk membuat file PostFactory.php dengan model Post.

<?php

namespace Database\Factories;

use App\Models\Post;
use Illuminate\Database\Eloquent\Factories\Factory;

class PostFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = Post::class;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        $user = \App\Models\User::inRandomOrder()->first();

        return [
            'user_id' => $user->id,
            'title' => $this->faker->sentence,
            'body' => $this->faker->text,
        ];
    }
} 

Setelah membuat PostFactory.php, kita harus mendefiniskan data-data seperti apa yang ingin dibuat pada field-field di posts table. Buka file database/factories/PostFactory.php, kemudian sesuaikan kode yang ada dengan kode seperti di atas.

Untuk file UserFactory kita tidak perlu membuatnya karena kita bisa menggunakan file UserFactory yang sudah disediakan by default oleh laravel.

php artisan tinker
User::factory()->count(10)->create()
Post::factory()->count(50)->create()

Sekarang kita akan generate file PostFactory dan UserFactory menggunakan tinker. Buka terminal, kemudian jalankan perintah-perintah seperti di atas secara berurutan.

Oke, kita sekarang sudah mempunyai data-data dummy pada table posts dan user. Dan selanjutnya kita akan menampilkan data-data posts pada file welcome.blade.php.

Menampilkan data post di View

Route::get('/', [App\Http\Controllers\FrontController::class, 'home']);

Buka file routes/web.php, ubah route::get('/') menjadi seperti di atas. Dengan kode route seperti di atas, saat kita mengakses URL root laravel project kita maka akan memanggil property home pada file FrontController.

php artisan make:controller FrontController

Pada langkah sebelumnya, kita memanggil property home yang ada di file FrontController sedangkan kita masih belum punya file FrontController. Untuk itu, kita perlu membuat file FrontController terlebih dahulu. Silahkan buka terminal, lalu jalankan perintah seperti di atas untuk membuat file FrontController.

<?php

namespace App\Http\Controllers;

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

class FrontController extends Controller
{
    public function home()
    {
        $posts = Post::all();
        return view('welcome', ['posts' => $posts]);
    }
}

Kemudian setelah file FrontController berhasil dibuat, silahkan buka file FrontController tersebut dan tambahkan property home dengan kode seperti di atas.

@extends('layouts.app')
@section('content')
<div class="container">
    @foreach ($posts as $post)
    <div class="card mb-3">
        <div class="card-header">
            {{ Carbon\Carbon::parse($post->created_at)->diffForHumans() }}
        </div>
        <div class="card-body">
            <h5 class="card-title">{{ $post->title }}</h5>
            <p class="card-text">{{ $post->body }}</p>
        </div>
        <div class="card-footer text-muted">
            <i class="bi bi-bookmark" style="font-size: 1.5em;"></i>
        </div>
    </div>
    @endforeach
</div>
@endsection

sekarang ubah kode di file welcome.blade.php menjadi seperti di atas. Di file welcome.blade.php ini kita akan menampilkan data-data dari table posts dengan menggunakan perulangan foreach.

Oke, sampai disini kita sudah berhasil menampilkan data-data dari table posts ke file welcome.blade.php. selanjutnya kita akan membuat fitur favorite dan unfavorite.

Membuat Fitur Favorite dan Unfavorite dengan Laravel 8 dan VueJS

Route::post('favorite/{post}', [App\Http\Controllers\FrontController::class, 'favorite']);
Route::post('unfavorite/{post}', [App\Http\Controllers\FrontController::class, 'unfavorite']);

Pertama, kita buat route untuk favorite dan unfavorite terlebih dahulu. Silahkan buka file routes/web.php, kemudian copy kode di atas lalu paste di file routes/web.php tersebut.

public function favorite(Post $post)
    {
        Auth::user()->favorites()->attach($post->id);
        return back();
    }

    public function unfavorite(Post $post)
    {
        Auth::user()->favorites()->detach($post->id);
        return back();
    }

Kemudian, kita buat property favorite dan unfavorite di FrontController.php dengan kode seperti di atas. Dan jangan lupa juga untuk menggunakan use Illuminate\Support\Facades\Auth; sebelum class FrontController.

property favorite() mengambil post_id sebagai argumen. Dengan menggunakan favorites relationship yang akan kita buat di User Model pada langkah selanjutnya. Kita akan attach post_id ke user_id (mengambil user id dari authentication), kemudian memasukkannya ke table favorites dan me-return kembali ke halaman sebelumnya.

Kemudian property unfavorite() adalah kebalikan dari property favorite(), yang akan menghapus user_id (mengambil user id dari authentication) dan post_id dari table favorites dengan detach.

public function favorites()
    {
        return $this->belongsToMany(Post::class, 'favorites', 'user_id', 'post_id')->withTimeStamps();
    }

Kemudian kita akan membuat belongstoMany relationship antara table user dengan table favorites. Silahkan buka file App/Models/User, lalu tambahkan kode seperti di atas.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Models\Favorite;
use Illuminate\Support\Facades\Auth;

class Post extends Model
{
    use HasFactory;

    public function favorited()
    {
        return (bool) Favorite::where('user_id', Auth::id())
                            ->where('post_id', $this->id)
                            ->first();
    }
} 

Selanjutnya buka file App/Models/Post, lalu buat property baru favorited dengan kode seperti di atas.

Membuat Vue Component

php artisan ui vue
npm install && npm run dev

Sekarang, mari kita mulai membuat vue component dengan menjalankan perintah-perintah di atas secara berurutan.

<template>
    <span>
        <a href="#" v-if="isFavorited" @click.prevent="unFavorite(post)">
            <i class="bi bi-bookmark-fill" style="font-size: 1.5em;"></i>
        </a>
        <a href="#" v-else @click.prevent="favorite(post)">
           <i class="bi bi-bookmark" style="font-size: 1.5em;"></i>
        </a>
    </span>
</template>

<script>
    export default {
        props: ['post', 'favorited'],

        data: function() {
            return {
                isFavorited: '',
            }
        },

        mounted() {
            this.isFavorited = this.isFavorite ? true : false;
        },

        computed: {
            isFavorite() {
                return this.favorited;
            },
        },

        methods: {
            favorite(post) {
                axios.post('/favorite/'+post)
                    .then(response => this.isFavorited = true)
                    .catch(response => console.log(response.data));
            },

            unFavorite(post) {
                axios.post('/unfavorite/'+post)
                    .then(response => this.isFavorited = false)
                    .catch(response => console.log(response.data));
            }
        }
    }
</script>

Oke, sekarang masuk ke folder resources/js/components lalu buat file baru dengan nama Favorite.vue. Jika sudah membuat file Favorite.vue, copy semua kode di atas lalu paste di file baru tersebut.

Dengan kode di atas, kita juga membuat logic saat mengirimkan response favorite atau unfavorite. by default, icon yang akan dimunculkan adalah bi bi-bookmark yang artinya saat icon diklik maka akan mengirimkan response favorite ke route favorite dan icon akan berubah ke bi bi-bookmark-fill.

Vue.component('favorite', require('./components/Favorite.vue').default);

Sebelum dapat menggunakan component Favorite.vue, kita perlu mendaftarkannya di file resources/js/app.js. Tambahkan script seperti di atas untuk mendaftarkan component yang baru kita buat sebelumnya.

npm run dev

Kemudian jalankan npm run dev.

@if (Auth::check())
<div class="card-footer text-muted">
    <favorite :post={{ $post->id }} :favorited={{ $post->favorited() ? 'true' : 'false' }}></favorite>
</div>
@endif

Oke, setelah mendaftarkan component baru di app.js, sekarang kita bisa menggunakan component tersebut view. Buka file welcome.blade.php, kemudian pada class card-footer, ubah menjadi seperti kode di atas. Kode di atas akan bekerja melakukan pengecekan authentication apakah user sudah login atau belum, jika sudah maka icon bookmark akan ditampilkan.

create favorite features with laravel 8 and vuejs

Sekarang silahkan buka project di browser maka icon bookmark tidak akan muncul. Tapi jika kita coba register akun terlebih dahulu atau login terlebih dahulu maka icon bookmark sudah berhasil muncul. Kemudian jika icon bookmark sudah muncul, silahkan coba klik salah satu icon bookmark maka icon tersebut akan berubah tampilannya dengan mengubah class icon yang dipanggil yaitu bi bi-bookmark-fill. Itu artinya fungsi favorite dan unfavorite sudah berjalan dengan baik. Di langkah selanjutnya kita akan coba menampilkan post-post favorite.

Menampilkan Favorite Post

Route::get('/my-favorites', [App\Http\Controllers\HomeController::class, 'myFavorites']);

Kita awali cara menampilkan favorite post dengan mendaftarkan route baru. Copy kode di atas, lalu tambahkan di file routes/web.php. Dengan route di atas, saya akan mengarahkannya ke property myFavorites di HomeController.php.

public function myFavorites()
    {
        $myFavorites = Auth::user()->favorites;

        return view('myFavorites', compact('myFavorites'));
    }

Sekarang buka file HomeController.php, kemudian tambahkan property myFavorites seperti di atas. Dan jangan lupa untuk menggunakan use Illuminate\Support\Facades\Auth;.

@extends('layouts.app')
@section('content')
<div class="container">
    <div class="text-center mb-3">
        <h3>My Favorite Posts</h3>
    </div>
    @foreach ($myFavorites as $post)
    <div class="card mb-3">
        <div class="card-header">
            {{ Carbon\Carbon::parse($post->created_at)->diffForHumans() }}
        </div>
        <div class="card-body">
            <h5 class="card-title">{{ $post->title }}</h5>
            <p class="card-text">{{ $post->body }}</p>
        </div>
        @if (Auth::check())
        <div class="card-footer text-muted">
            <favorite
                :post={{ $post->id }}
                :favorited={{ $post->favorited() ? 'true' : 'false' }}
                >
            </favorite>
        </div>
        @endif
    </div>
    @endforeach
</div>
@endsection

Di property myFavorites yang baru saja kita buat di HomeController, kita mengarahkan ke view myFavorites. Jadi kita perlu membuat file view baru dengan nama myFavorites.blade.php. Silahkan buat file myFavorites.blade.php tersebut di dalam folder views, kemudian copy semua kode di atas dan paste di file baru tersebut.

laravel vuejs favorite feature

Oke, dengan ini kita sudah berhasil membuat view yang menampilkan data-data favorite posts. Untuk mempermudah navigasi, mari kita tambahkan item di file layouts/app.blade.php dengan menambahkan kode <a href="/my-favorites" class="dropdown-item">My Favorites</a> tepat di atas kode <a class="dropdown-item" href="{{ route('logout') }}"

Sekian artikel tentang cara membuat fitur favorite atau save seperti instagram dengan laravel 8 dan VueJS. Sampai disini, kita sudah berhasil membuat fitur favorite dan unfavorite. Kita juga sudah bisa menampilkan data-data favorite post.

Jika ada kritik, saran atau apapun itu yang ingin didiskusikan, silahkan tulis komentar kalian di form komentar yang tersedia di bawah ini. Selamat mencoba dan sampai jumpa di artikel berikutnya.

 

Web illustrations by Storyset

Tinggalkan Komentar
Loading Comments