How To Create Basic CRUD App With VueJs and Laravel

admin_img Posted By Bajarangi soft , Posted On 27-11-2020

CRUD App four basic operations: Create, Read, Update, Delete.A CRUD application is one that uses forms to get data into and out of a database.So today we discuss how to do it using vuejs and laravel

How To Create Basic CRUD App With VueJs and Laravel

Let's learn

1.Install new laravel project to implement code. https://laravel.com/docs/5.8/installation

composer create-project --prefer-dist laravel/laravel blog

run above command in command prompt.

2.Install node.js package for blog project . click here to download it.
3.Install npm package for blog project.click here to see the documentation.Install the dependencies in the local node_modules folder.

npm install

run above command in terminal.

4.Connect database using env file.

DB_DATABASE=VUEjs
DB_USERNAME=root
DB_PASSWORD=

5.Create controller model and migration files using below code 

php artisan make:model Task -mcr


6.Open blog/app/Task.php model file and implement below code in it.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Task extends Model
{
    //
    protected $fillable = ['name'];
}


7.Open blog/database/migrations/2020_11_26_081412_create_Tasks_table.php and implement below code in it.

<?php

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

class CreateTasksTable extends Migration
{
    public function up()
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('tasks');
    }
}

8.Open blog/app/Http/Controllers/TaskController.php and implement as below code.

<?php

namespace App\Http\Controllers;

use App\Task;
use Illuminate\Http\Request;
use App\Http\Requests\TaskRequest;

class TaskController extends Controller
{
    public function index($term = null)
    {

        if($term != null){
        $tasks['data']=Task::where('name','like','%'.$term.'%')->get();
        return request()->json(200,$tasks);
        }
        return $this->_getRecord();
    }

    public function create()
    {
        //
    }

 
    public function store(Request $request)
    {
        $this->validate($request, [
            'name' => 'required | min:5',
        ]);
        $task=Task::create($request->all());
        if($task){
            return $this->_getRecord();
        }
    }

   
    public function show(Task $task)
    {
        return request()->json(200,$task);
    }

   
    public function edit(Task $task)
    {
        return request()->json(200,$task);
    }

   
    public function update(TaskRequest $request, Task $task)
    {
        $task->name =$request->name;
        if($task->save()){
           return $this->_getRecord();
        }
    }

  
    public function destroy(Task $task)
    {

        if($task->delete()){
            return $this->_getRecord();
        }
        else{
            return response()->json(425,['delete'=>'error deleting record']);
        }
    }
    private function _getRecord(){
        $task=Task::orderBy('created_at','desc')->paginate(5);
        return request()->json(200,$task);
    }
}


9.Now Open your /resources/js/components/, and create TaskComponent.vue
TaskComponent.vue

<template>
    <div class="container">
        <div class="row justify-content-center">
            <h1>Basic CRUD App With VueJs and Laravel</h1><br>
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">
                        <h2>Tasks All Do Component <span class="float-right">
                            <button class="btn btn-success btn-xs" data-toggle="modal"  data-target="#myModal">+</button></span></h2></div>
                    <div class="card-body">
                        <input type="search" v-model="search" value="" class="form-control" @keyup="searchRecord" placeholder=""/>
                        <ul class="list-group" >
                            <li class="list-group-item" v-for="t in tasks.data">{{ t.id }}-{{ t.name }}
                                <span class="float-right">
                                    <a class="btn btn-success btn-xs" data-toggle="modal"  data-target="#editModal" @click="getRecord(t.id)"> Edit</a> |
                                    <button class="btn btn-danger btn-xs" @click="delRecord(t.id)">Delete</button> |
                                    <button class="btn btn-info btn-xs" data-toggle="modal"  data-target="#viewModal" @click="getRecord(t.id)">Preview</button>
                                </span>
                            </li>

                        </ul>
                        <div class="mb-2"></div>
                        <pagination :data="tasks.data" @pagination-change-page="getResults"></pagination>
                    </div>
                    <div class="card-footer text-right"><small>Copyright &copy:2020,Bajarabjsoft</small></div>
                </div>
            </div>
        </div>
        <div id="model">
            <addtask @recordadded="refreshRecord"></addtask>
            <edittask :rec="editRec" @recordUpdate="refreshRecord"></edittask>
            <viewtask :viewRec="editRec" @recordview="refreshRecord"></viewtask>
        </div>
    </div>
</template>
<script type="text/javascript">
    Vue.component('pagination', require('laravel-vue-pagination'));
    Vue.component('addtask', require('./addModelComponent.vue').default);
    Vue.component('edittask', require('./editModalComponent.vue').default);
    Vue.component('viewtask', require('./viewModalComponent.vue').default);
    export default {
        data(){
        return{
            tasks:{},//objects
            records:{},
            editRec:{},
            errors:{},
            search:'',

            }
        },
        methods:{
            getResults(page) {
                if(typeof page === 'undefined'){
                    page=1;
                }
                axios.get('http://localhost/blog/public/tasks?page=' + page)
                    .then(response => this.tasks = response.data)
                    .catch(error=>console.log(error));
            },
            refreshRecord(record){
                this.tasks=record.data
            },
            getRecord  (id){
                if(typeof id === 'undefined'){
                    id=1;
                }
                console.log(id);
                axios.get('http://localhost/blog/public/tasks/' + id +'/edit')
                    .then(response => this.editRec = response.data)
                    .catch(error=> this.errors = error.response.data.errors);
            },
            delRecord(id){
                const reply =confirm("Are You Sure..? You want to delete this record from record list");
                if(typeof id === 'undefined'){
                    id=1;
                }
                if(reply){
                    console.log(id);
                    axios.post('http://localhost/blog/public/tasks/' + id ,{
                        'id':id,
                        '_method':'DELETE',
                    })
                        .then(response => this.tasks=response.data)
                        .catch(error=> this.errors = error.response.data.errors);
                } else {
                    return
                }


            },
            searchRecord(){
                if(this.search.length >= 3){

                    axios.get('http://localhost/blog/public/search/'+this.search)
                        .then(respone=>this.tasks =respone.data)
                        .catch((error)=>console.log(error));
                }else{
                    this.getResults();
                }
            }
        },
        created(){
            axios.get('http://localhost/blog/public/tasks')
                .then((response)=>this.tasks=response.data)
                .catch((error)=>console.log(error));
            console.log('Tasks Component loaded.');
        }

    }
</script>
<style type="text/css" scoped></style>

10.Now Open your /resources/js/components/, and create addModelComponent.vue
addModelComponent.vue
<template>
    <!-- Trigger the modal with a button -->
    <!--<button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">Open Modal</button>-->

    <!-- Modal -->
    <div class="modal fade" id="myModal" role="dialog">
        <div class="modal-dialog">

            <!-- Modal content-->
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="">Add New Record</h5>
                    <button type="button" class="close" data-dismiss="modal" @click="clearmodal">&times;</button>
                </div>
                <div class="modal-body">
                    <p class="alert alert-success" v-if="success.length>0">{{success}}</p>
                    <textarea name="name" id="name" class="form-control" v-model="record"></textarea>
                    <ul v-if="error" class="list-unstyled">
                        <li v-for="err of error" class="alert alert-danger">{{err}}</li>
                    </ul>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-success" @click="addRecord">Save</button>
                    <button type="button" class="btn btn-default" @click="clearmodal" data-dismiss="modal">Close</button>
                </div>
            </div>

        </div>
    </div>
</template>
<script type="text/javascript">
    export default {
        mounted() {
            console.log('Add Model Component mounted.')
        },
        data(){
            return{
                record:'',
                error:[],
                success:'',
            }
        },
        methods:{
            addRecord(){
                axios.post('http://localhost/blog/public/tasks',{
                    'name':this.record,
                })
                    .then(data =>{
                        this.$emit('recordadded',data);
                        this.success= "Task Added Successfully!!";
                    })
                    .catch(error =>{
                        this.error = error.response.data.errors.name;
                    });
                    this.record='';
                this.error=[];
            },
            clearmodal(){
                this.error=[];
                this.record='';
                this.success='';
            }
        }
    }
</script>
<style type="text/css" scoped></style>

11.Now Open your /resources/js/components/, and create editModalComponent.vue
editModalComponent.vue
<template>
    <!-- Trigger the modal with a button -->
    <!--<button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">Open Modal</button>-->

    <!-- Modal -->
    <div class="modal fade" id="editModal" role="dialog">
        <div class="modal-dialog">

            <!-- Modal content-->
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="">Edit Record</h5>
                    <button type="button" class="close" data-dismiss="modal" @click="clearmodal">&times;</button>
                </div>
                <div class="modal-body">
                    <p class="alert alert-success" v-if="success.length>0">{{success}}</p>
                    <textarea name="name" id="name" class="form-control" v-model="rec.name"></textarea>
                    <ul v-if="error" class="list-unstyled">
                        <li v-for="err of error" class="alert alert-danger">{{err}}</li>
                    </ul>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-success" @click="updateRecord">Update</button>
                    <button type="button" class="btn btn-default" @click="clearmodal" data-dismiss="modal">Close</button>
                </div>
            </div>

        </div>
    </div>
</template>
<script type="text/javascript">
    export default {
        props:['rec'],
        mounted() {
            console.log('Add Model Component mounted.')
        },
        data(){
            return{
                error:[],
                success:'',
            }
        },
        methods:{
            updateRecord(){
                axios.post('http://localhost/blog/public/tasks/'+this.rec.id,{
                    'name':this.rec.name,
                    '_method':'PUT',
                })
                    .then(data =>{
                        this.$emit('recordUpdated',data);
                        this.success= "Task updated Successfully!!";
                    })
                    .catch(error =>{
                        this.error = error.response.data.errors.name;
                    });

                this.error=[];
            },
            clearmodal(){
                this.error=[];
                this.success='';
            }
        }
    }
</script>
<style type="text/css" scoped></style>

12.Now Open your /resources/js/components/, and create viewModalComponent.vue
viewModalComponent.vue
<template>
    <!-- Trigger the modal with a button -->
    <!--<button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">Open Modal</button>-->

    <!-- Modal -->
    <div class="modal fade" id="viewModal" role="dialog">
        <div class="modal-dialog">

            <!-- Modal content-->
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="">Veiw Record {{viewRec.id}}</h5>
                    <button type="button" class="close" data-dismiss="modal" >&times;</button>
                </div>
                <div class="modal-body">
                    <p id="name">{{viewRec.name}}</p>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                </div>
            </div>

        </div>
    </div>
</template>
<script type="text/javascript">
    export default {
        props:['viewRec'],
    }
</script>
<style type="text/css" scoped></style>

13.Now Include components in blog/resources/js/app.js file as below.
require('./bootstrap');

window.Vue = require('vue');

import VueRouter from 'vue-router'
Vue.use(VueRouter)
const example = require('./components/ExampleComponent.vue').default;
const tasks = require('./components/TaskComponent.vue').default;
const routes=[
    {
        path: '/',
        component: tasks
    },
    {
        path: '/example',
        component: example
    },

];

const router=new VueRouter({
    routes
});
const app = new Vue({
    el: '#app',
    router,
    data: {
    },
});
 

14.Now view content using welcome.blade.php file.

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Vuejs auto reload digital clock</title>
        <link href="{{asset('css/app.css')}}" rel="stylesheet">
        <meta name="csrf-token" content="{{csrf_token()}}"/>
        <!-- Fonts -->


        <!-- Styles -->
        <style>
            html, body {
                color: black;
                font-family: 'Nunito', sans-serif;
                font-weight: 200;
                height: 100vh;
                margin: 0;
                background:white;

            }
            .title-title{
                font-size: 70px;
            }
            .position-ref {
                position: relative;
            }

            .top-right {
                position: absolute;
                right: 10px;
                top: 18px;
            }

            .content {
                text-align: center;
            }

            .title {
                font-size: 84px;
            }

            .links > a {
                color: #636b6f;
                padding: 0 25px;
                font-size: 13px;
                font-weight: 600;
                letter-spacing: .1rem;
                text-decoration: none;
                text-transform: uppercase;
            }

            .m-b-md {
                margin-bottom: 30px;
            }
            a {
                color: white;
                text-decoration: none;
                background-color: transparent;
            }
            a:hover {
                color: white;
                text-decoration: underline;
            }
        </style>
    </head>
    <body >
    <div id="app">
        <nav class="navbar navbar-expand-lg navbar-light bg-dark">
            <div class="container">
                <a class="navbar-brand  text-white" href="#" style="font-size: 25px">Blog</a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>

                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <ul class="navbar-nav ml-auto text-white">
                        <li class="text-white">
                            <router-link to="/">Task</router-link>
                                <router-link to="/sample">Sample</router-link>
                                <router-link to="/example">Example</router-link>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
        <div class="container mt-5">
            <router-view></router-view>
        </div>
    </div>
    <script src="{{asset('js/app.js')}}"></script>
    </body>
</html>

15.Create route in web.php
Route::resource('tasks','TaskController');

16.Run command npm run watch.

npm run dev  active and  updates only when you run command.
npm run watch does the same, but then it stays active and "watches" for updates.vue and .js files. If it detects a change so you can just refresh the page.


17.Now run below url in google chrome.

http://localhost/blog/public/

Related Post