How to Build Laravel 10 Vue JS Like Dislike System

Last Updated on by in Laravel

In this Laravel Vue JS Like Dislike System example tutorial, you will learn how to create a like and dislike system in the Laravel Vue JS application; moreover, we will show you how to store the like and dislike values in the database based on the user id.

Like dislike systems are majorly seen in social media, blog sites, like the user’s emotion, represent the love for the content or post, whereas dislike is equal to hate.

This system enhances the user experience and attains the user’s feedback for your content like a dislike system is a way to convert an experience into a concrete object.

Throughout this step by step tutorial, you will learn how to quickly implement like dislike system from scratch in the laravel vue js app.

Laravel 10 Vue JS Like Dislike System Tutorial Overview

We will explain to you how to create a laravel app from the beginning, make the database connection, generate and configure model, run migration, define routes, generate and set up the controller to handle the like dislike system core logic, how to set up vue components in laravel app, how to configure the view to display the like dislike system on the frontend.

Create Laravel Project

Open terminal and begin with given below command to install a new laravel application:

composer create-project laravel/laravel laravel-vue-like-dislike-system --prefer-dist

Connect Database

Next, move to your project root folder, look for .env configuration file equally important add the database details as shown below:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=databse
DB_USERNAME=root
DB_PASSWORD=

If you are using MAMP local server in macOs; make sure to append UNIX_SOCKET and DB_SOCKET below database credentials in .env file.

UNIX_SOCKET=/Applications/MAMP/tmp/mysql/mysql.sock
DB_SOCKET=/Applications/MAMP/tmp/mysql/mysql.sock

Set Up Model and Run Migration

In the second step, you have to generate a model and migration file:

php artisan make:model Blog -m

Place below code in database/migrations/create_blogs_table.php:

<?php

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

class CreateBlogsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('blogs', function (Blueprint $table) {
            $table->id();
            $table->string('post_title');
            $table->string('post_slug');
            $table->unsignedBigInteger('user_id');
            $table->unsignedBigInteger('like')->default(0);
            $table->unsignedBigInteger('dislike')->default(0);            
            $table->timestamps();
        });
    }

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

Place the below code in app/Models/Blog.php:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Blog extends Model
{
    use HasFactory;
    protected $fillable = [
        'post_title', 
        'description'
    ];
 
    public function getRouteKeyName()
    {
        return 'post_slug';
    }    
}

Afterwards, run the following command for database migration:

php artisan migrate

Generate Fake Data

This step tells you how to generate test data that will be used for the like dislike component:

php artisan make:factory BlogFactory --model=Blog

Add following code in database\factories\BlogFactory.php:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Blog extends Model
{
    use HasFactory;
    
    protected $fillable = [
        'post_title', 
        'description'
    ];
 
    public function getRouteKeyName()
    {
        return 'post_slug';
    }    
}

Execute tinker command in console:

php artisan tinker

Above command will take you inside the Psy shell, then run the below command:

Blog::factory()->count(30)->create()

Install Vue UI and NPM Dependencies

Run composer command to install Vue UI in laravel, it will manifest vue laravel scaffold:

composer require laravel/ui
php artisan ui vue

Subsequently, execute the command to install npm packages:

npm install

Build New Controller

In this step, you have to generate a new controller and define the code to build like dislike logic:

php artisan make:controller BlogController

After that, open app\Http\Controllers\BlogController.php file, and place the below code within:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Facades\App\Repository\Blogs;
use App\Models\Blog;

class BlogController extends Controller
{
    public function index()
    {
        $blogs = Blog::latest()->get();
        return view('blog', ['blogs' => $blogs ]);
    }
 
    public function blogDetail(Blog $post_slug)
    {
        return view('blog-details', ['blog' => $post_slug ]);
    }
 
    public function fetchLike(Request $request)
    {
        $blog = Blog::find($request->blog);
        return response()->json([
            'blog' => $blog,
        ]);
    }
 
    public function handleLike(Request $request)
    {
        $blog = Blog::find($request->blog);
        $value = $blog->like;
        $blog->like = $value+1;
        $blog->save();
        return response()->json([
            'message' => 'Liked',
        ]);
    }    
 
    public function fetchDislike(Request $request)
    {
        $blog = Blog::find($request->blog);
        return response()->json([
            'blog' => $blog,
        ]);
    }
 
    public function handleDislike(Request $request)
    {
        $blog = Blog::find($request->blog);
        $value = $blog->dislike;
        $blog->dislike = $value+1;
        $blog->save();
        return response()->json([
            'message' => 'Disliked',
        ]);
    }
}

Create Routes

In this step, you have to create the routes for handling the like and dislike functions, so open and add the below code in routes/web.php file:

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\BlogController;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
*/
 
Route::get('/blog', [BlogController::class, 'index']);
Route::get('/blog/{post_slug?}', [BlogController::class, 'blogDetail'])->name('blog');
 
Route::post('/like', [BlogController::class, 'fetchLike']);
Route::post('/like/{id}', [BlogController::class, 'handleLike']);
 
Route::post('/dislike', [BlogController::class, 'fetchDislike']);
Route::post('/dislike/{id}', [BlogController::class, 'handleDislike']);

Create Like Dislike Vue Components

This step explains how to create like dislike Vue components, so head over to resources/assets/js/components directory. Here, create two files, name them LikeComponent.vue not only but also DislikeComponent.vue.

Add below code in resources/js/components/LikeComponent.vue file:

<template>
    <div class="container">
        <div id="success" class="mb-3"></div>

        <a style="cursor: pointer" @click.prevent="likeBlog">
            <i class="fa fa-thumbs-o-up" aria-hidden="true"></i>
            ({{ alllikes }})
        </a>
    </div>
</template>

<script>
    export default {
        props: ['blog'],
        data() {
            return {
                alllikes: '',
            }
        },
        methods: {
            likeBlog() {
                axios.post('/like/' + this.blog, {
                        blog: this.blog
                    })
                    .then(res => {
                        this.renderLike()
                        $('#success').html(res.data.message)
                    })
                    .catch()
            },
            renderLike() {
                axios.post('/like', {
                        blog: this.blog
                    })
                    .then(res => {
                        console.log(res.data.blog.like)
                        this.alllikes = res.data.blog.like
                    })
            }
        },
        mounted() {
            this.renderLike()
        }
    }

</script>

Place the code in resources/js/components/DislikeComponent.vue file:

<template>
    <div class="container">
        <div id="success" class="mb-3"></div>
        
       <a style="cursor: pointer" @click.prevent="dislikeBlog">
           <i class="fa fa-thumbs-o-down" aria-hidden="true"></i> 
           ({{ allDislike }})
       </a>
    </div>
</template>
 
<script>
    export default {
        props:['blog'],
        data(){
            return {
                allDislike:'',
            }
        },
        methods:{
            dislikeBlog(){
                axios.post('/dislike/'+this.blog, {blog: this.blog})
                .then(res =>{
                    this.renderDislike()
                    $('#success').html(res.data.message)
                })
                .catch()
            },
            renderDislike(){
                axios.post('/dislike', {blog:this.blog})
                .then(res =>{
                    console.log(res.data.blog.dislike)
                    this.allDislike = res.data.blog.dislike
                })
            }
        },
        mounted() {
            this.renderDislike()
        }
    }
</script>

Now, gradually register like and dislike vue components in resources/js/app.js file:

require('./bootstrap');

window.Vue = require('vue');

Vue.component('like-component', require('./components/LikeComponent.vue').default);
Vue.component('dislike-component', require('./components/DislikeComponent.vue').default);


/**
 * Next, we will create a fresh Vue application instance and attach it to
 * the page. Then, you may begin adding components to this application
 * or customize the JavaScript scaffolding to fit your unique needs.
 */

const app = new Vue({
    el: '#app',
});

Setting Up Vue Component in Blade View

Now, you have to create a blog.blade.php file in the resources/views/ folder, add the following code in the resources/views/blog.blade.php file:

@extends('layout.app')
 
@section('content')

<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">Blogs</div>
 
                <div class="card-body">
                    <ul>
                        @foreach ($blogs as $data)
                         <a href="{{ route('blog', $data->post_slug) }}"><li>{{ $data->post_title }}</li></a>
                        @endforeach
                    </ul>
                </div>
                 
            </div>
        </div>
    </div>
</div>

@endsection

Next, you need to create a blog-details.blade.php file in the resources/views/ folder, put the below code in the resources/views/blog-details.blade.php file:

@extends('layout.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">Blog Detail</div>

                <div class="card-body">
                    <h2>{{ $blog->post_title }}</h2>

                    <like-component :blog="{{ $blog->id }}"></like-component>
                    <dislike-component :blog="{{ $blog->id }}"></dislike-component>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

In this step you need to create layout folder in resources/views/ directory, also create app.blade.php file and then add the below code in resources/views/layout/app.blade.php file:

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}">
 
    <title>Laravel Vue JS Like Dislike Demo</title>
 
    <script src="{{ asset('js/app.js') }}" defer></script>
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.0.0/css/font-awesome.min.css" rel="stylesheet">

</head>
<body>
    <div id="app">
 
        <main class="py-4">
            @yield('content')
        </main>
 
    </div>
</body>
</html>

Run Like Dislike System

This step brings you to the final step of this tutorial, now you have to start the laravel as well as node server.

Open terminal and execute the following command:

npm run watch

Also, run the below command in another console:

php artisan serve

Open the URL to test the app:

http://127.0.0.1:8000/blog

Laravel Vue JS Like Dislike System Example

Summary

Ultimately, the laravel Vue JS like dislike tutorial is over; in this comprehensive tutorial, you have learned how to easily integrate Vue JS like dislike system in a laravel Vue application from the absolute beginning.

Also, you can see how to store like dislike counts based on specific user id into the database.