Laravel 5.5 crud application with Vue.js

  • Posted by Sharad Jaiswal

    In this tutorial, we are going to create a simple crud application using Vue js and Laravel. We going to use Vue.js 2.x for frontend and Laravel 5.5 for creating our backend web services.

    Follow below steps to create Crud Application in Laravel 5.5 and Vue Js.

    Installing and configuring Laravel 5.5

    Installing Laravel 5.5

    If you have not installed Laravel on your server, then run following commands to install and configure Laravel 5.5 on your server

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

    Configuring file permissions

    Once installation of Laravel framework is complete successfully then you need to provide read-write permission to below folders

    • storage/
    • bootstrap/cache

    Run the following command to provide read-write permission

    sudo chmod -R 777 storage
    sudo chmod -R 777 bootstrap/cache
    

    Configuring database connection

    In Laravel, you can configure your database connection by editing following fields in your .env file. .env file is situated in Laravel root directory.

    DB_CONNECTION=mysql
    DB_HOST=127.0.0.1
    DB_PORT=3306
    DB_DATABASE=your database name
    DB_USERNAME=your mysql username
    DB_PASSWORD=your mysql password
    

    Creating Our tables and Models

    In this step we are going to create migrations for our table, then model for our Laravel Crud Application

    Creating Table Migrations

    Open your command line interface and type the following command to generate table migration for our crud app

    php artisan make:migration create_posts_table

    Once above command is executed successfully a new file named something like 2017_09_23_180359_create_posts_table.php is created in your database/migrations directory. Open that file and put following code in it.

    &lt?php
    
    use Illuminate\Support\Facades\Schema;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Database\Migrations\Migration;
    
    class CreatePostsTable extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            Schema::create('posts', function (Blueprint $table) {
                $table->increments('id');
                $table->string('name');
                $table->text('description');
                $table->timestamps();
            });
        }
    
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::dropIfExists('posts');
        }
    }
    
    

    After saving above file run below command to migrate your tables.This will create a new table in your database named posts.

    php artisan migrate

    Posts-table-structure-mysql

    Creating Model

    In order to do queries with the database using Eloquent in Laravel, we need to create a Model. Let's create our Posts Model by running below command on our terminal.

    php artisan make:model Post

    running above command will create a new file name Post.php in our app directory. Open that file and add following code in that.

    &lt?php
    
    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Post extends Model
    {
        protected $fillable = ['name','description'];
    }
    Also, Read Laravel interview questions

    Creating controllers and register it in Routes for API's in Laravel

    Generating Controller

    In Laravel, you can generate your controller by running below command on your terminal

    php artisan make:controller ApisController
    

    Now open your app/Http/Controller/ApisController.php add following code in it

    <?php
    
    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    
    use App\Post;
    
    class ApisController extends Controller
    {
         
    	 
    	/**
         * Display our Vue js landing Page.
         *
         * @return \Illuminate\Http\Response
        */
        public function home()
        {
              return view('vueApp');
        }
    	 
    	 
    	/**
         * Display a listing of the resource.
         *
         * @return \Illuminate\Http\Response
        */
        public function index()
        {
          return Post::orderBy('id','DESC')->get();
        }
    	
    	
    
    	/**
         * Store a newly created resource in storage.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return \Illuminate\Http\Response
         */
        public function store(Request $request)
        {
    		
    		
            $this->validate($request, [
                'name' => 'required',
                'description' => 'required',
            ]);
    
            $create = Post::create($request->all());
    
            return response()->json(['status'=>'success','msg'=>'Post created successfully']);
    		
        }
    	
    	/**
         * Display the specified resource.
         *
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function show($id)
        {
            //
    		return Post::find($id);
        }
    	
    	/**
         * Show the form for editing the specified resource.
         *
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function edit($id)
        {
            //
    		return Post::find($id);
        }
    
    	/**
         * Update the specified resource in storage.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function update(Request $request, $id)
        {
            $this->validate($request, [
                'name' => 'required',
                'description' => 'required',
            ]);
    
            $post = Post::find($id);
    		if($post->count()){
    			 $post->update($request->all());
    			 return response()->json(['status'=>'success','msg'=>'Post updated successfully.']);
    		}else{
    			 return response()->json(['status'=>'error','msg'=>'Error in updating Post']);
    		}
         
        }
    
        /**
         * Remove the specified resource from storage.
         *
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function destroy($id)
        {
            $post= Post::find($id);
    		if($post->count()){
    			$post->delete();
    			 return response()->json(['status'=>'success','msg'=>'Post deleted successfully']);
    		}else{
    			 return response()->json(['status'=>'error','msg'=>'Error in deleting Post']);
    		}
        }
    }
    
    
    
    

    Registering our Routes

    Open your routes/web.php and add below codes in it.

    Route::get('/', 'ApisController@home');
    Route::resource('/api','ApisController');
    

    Setting and configuring Vue js with Laravel 5.5

    In this step, we going to install all Vue js dependencies using NPM, create Vue components and write and configure Vue methods to interact with our Laravel API's

    Read Some good interview Questions on Vue JS.

    Installing Vue dependencies

    Run below command to install Vue js and bootstrap Frontend dependencies

    npm install

    Install vue-router by running below command for Vue js routing

    npm install vue-router

    Install vue-axios by running below command for Vue js api calls

    npm install vue-axios

    Once the dependencies of have been installed using npm install, you can compile your SASS files to plain CSS using Laravel Mix. Run npm run dev command on the terminal to process the instructions written in your webpack.mix.js file. npm run dev command will process the instruction written in webpack.mix.js file and place your compiled CSS and js in public/css and public/js directory.

    npm run dev
    npm run watch

    Configuring Vue.js App and initializing Modules.

    Open app.js file you can found it in resources/assets/js/ directory and add following code in it.

    /**
     * First we will load all of this project's JavaScript dependencies which
     * includes Vue and other libraries. It is a great starting point when
     * building robust, powerful web applications using Vue and Laravel.
     */
    
    require('./bootstrap');
    
    window.Vue = require('vue');
    
    window.VueRouter=require('vue-router').default;
    
    window.VueAxios=require('vue-axios').default;
    
    window.Axios=require('axios').default;
    
    let AppLayout= require('./components/App.vue');
    
    const Listposts=Vue.component('Listposts', require('./components/Listposts.vue'));
    const Addpost =Vue.component('Addpost', require('./components/Addpost.vue'));
    const Editpost =Vue.component('Editpost', require('./components/Editpost.vue'));
    const Deletepost =Vue.component('Deletepost', require('./components/Deletepost.vue'));
    const Viewpost =Vue.component('Viewpost', require('./components/Viewpost.vue'));
    
    // registering Modules
    Vue.use(VueRouter,VueAxios, axios);
    
    const routes = [
     {
     name: 'Listposts',
     path: '/',
     component: Listposts
     },
     {
     name: 'Addpost',
     path: '/add-post',
     component: Addpost
     }
     ,
     {
     name: 'Editpost',
     path: '/edit/:id',
     component: Editpost
     }
     ,
     {
     name: 'Deletepost',
     path: '/post-delete',
     component: Deletepost
     },
     {
     name: 'Viewpost',
     path: '/view/:id',
     component: Viewpost
     }
    ];
    
    
    const router = new VueRouter({ mode: 'history', routes: routes});
    
    new Vue(
     Vue.util.extend(
     { router },
     AppLayout
     )
    ).$mount('#app');
    
    
    

    Creating your Vue components to create, edit, delete, list, view posts.

    All vue js components are kept in resources/assets/js/components directory.

    Creating a layout for our Vue App.

    Create a new file App.vue in resources/assets/js/components directory and put following code in it.

    <template>
     <div class="container">
     <div>
     <transition name="fade">
     <router-view></router-view>
     </transition>
     </div>
     </div>
    </template>
    
    <style>
     .logo {
     width: 50px;
     float: left;
     margin-right: 15px;
     }
    
     .form-group {
     max-width: 500px;
     }
    
     .actions {
     padding: 10px 0;
     }
    
     .glyphicon-euro {
     font-size: 12px;
     }
    
     .fade-enter-active, .fade-leave-active {
     transition: opacity .5s
     }
     .fade-enter, .fade-leave-active {
     opacity: 0
     }
    </style>
    
    
    <script>
     export default {
     mounted() {
     console.log('Component mounted.')
     }
     }
    </script>

    Creating Vue component to list posts.

    Create a new file Listposts.vue in resources/assets/js/components directory and put following code in it.

    Listing records in Vue js

    // Listposts.vue
    <template id="post-list">
     <div>
     <div class="actions">
     <router-link class="btn btn-default" v-bind:to="{path: '/add-post'}">
     <span class="glyphicon glyphicon-plus"></span>
     Add Post
     </router-link>
     </div>
     <div class="filters row">
     <div class="form-group col-sm-3">
     <label for="search-element">Post name</label>
     <input v-model="searchKey" class="form-control" id="search-element" requred/>
     </div>
     </div>
     <table class="table">
     <thead>
     <tr>
     <th>Name</th>
     <th>Description</th>
     <th class="col-sm-2">Actions</th>
     </tr>
     </thead>
     <tbody>
     <tr v-for="post in filteredPosts">
     <td>
     <router-link v-bind:to="{name: 'Viewpost', params: {id: post.id}}">{{ post.name }}</router-link>
     </td>
     <td>{{ post.description }}</td>
     
     <td>
     <router-link class="btn btn-warning btn-xs" v-bind:to="{name: 'Editpost', params: {id: post.id}}">Edit</router-link>
     <router-link class="btn btn-danger btn-xs" v-bind:to="{name: 'Deletepost', params: {id: post.id}}">Delete</router-link>
     </td>
     </tr>
     </tbody>
     </table>
     </div>
    </template>
    
    <script>
     export default {
     data:function () {
     return {posts: '', searchKey: ''};
     },
     created: function(){
     let uri = 'http://127.0.0.1:8000/api/';
     Axios.get(uri).then((response) => {
     
     this.posts = response.data;
     });
     
     },
     computed: {
     filteredPosts: function () {
     if(this.posts.length){
     return this.posts.filter(function (post) {
     return this.searchKey=='' || post.name.indexOf(this.searchKey) !== -1;
     },this);
     }
     }
     }
     
     }
     
    
    </script>

    Creating Vue component for add post.

    Create a new file Addpost.vue in resources/assets/js/components directory and put following code in it.

    Creating Record in Vue js 2.1

    // Adposts.vue
    <template id="add-post">
     <div>
     <h2>Add new post</h2>
     <form v-on:submit.prevent="createPost">
     <div class="form-group">
     <label for="add-name">Name</label>
     <input class="form-control" id="add-name" v-model="post.name" required/>
     </div>
     <div class="form-group">
     <label for="add-description">Description</label>
     <textarea class="form-control" id="add-description" rows="10" v-model="post.description"></textarea>
     </div>
     
     <button type="submit" class="btn btn-primary">Create</button>
     <router-link class="btn btn-default" v-bind:to="'/'">Cancel</router-link>
     </form>
     </div>
    </template>
    
    
    <script>
     export default {
     
     data: function () {
     return {post: {name: '', description: ''}}
     },
     methods: {
     createPost: function() {
     let uri = 'http://127.0.0.1:8000/api/';
     Axios.post(uri, this.post).then((response) => {
     this.$router.push({name: 'Listposts'}) 
     
     })
     
     }
     }
    
     }
    </script>

    Creating Vue component for Edit post.

    Create a new file Editpost.vue in resources/assets/js/components directory and put following code in it.

    Editing Record in Vue.js

    //Editpost.vue
    <template id="post-edit">
     <div>
     <h2>Edit post</h2>
     <form v-on:submit.prevent="updatePost">
     <div class="form-group">
     <label for="edit-name">Name</label>
     <input class="form-control" id="edit-name" v-model="post.name" required/>
     </div>
     <div class="form-group">
     <label for="edit-description">Description</label>
     <textarea class="form-control" id="edit-description" rows="3" v-model="post.description"></textarea>
     </div>
    
     <button type="submit" class="btn btn-primary">Save</button>
     <router-link class="btn btn-default" v-bind:to="'/'">Cancel</router-link>
     </form>
     </div>
    </template>
    
    <script>
     export default {
     
     data: function () {
     return {post: {name: '', description: ''}}
     },
     created: function(){
     let uri = 'http://127.0.0.1:8000/api/'+this.$route.params.id+'/edit';
     Axios.get(uri).then((response) => {
     this.post = response.data;
     });
     
     },
     methods: {
     updatePost: function() {
     let uri = 'http://127.0.0.1:8000/api/'+this.$route.params.id;
     Axios.patch(uri, this.post).then((response) => {
     this.$router.push({name: 'Listposts'}) 
     
     })
     
     }
     }
    
     }
    </script>
    
    

    Creating Vue component for Delete post.

    Create a new file Deletepost.vue in resources/assets/js/components directory and put following code in it.

    Deleting records in Vue js

    //Deletepost.vue
    <template id="post-delete">
     <div>
     <h2>Delete post {{ post.name }}</h2>
     <form v-on:submit.prevent="deletePost">
     <p>The action cannot be undone.</p>
     <button type="submit" class="btn btn-danger">Delete</button>
     <router-link class="btn btn-default" v-bind:to="'/'">Cancel</router-link>
     </form>
     </div>
    </template>
    
    <script>
     export default {
     
     data: function () {
     return {post: {name: '', description: ''}}
     },
     created: function(){
     let uri = 'http://127.0.0.1:8000/api/'+this.$route.params.id+'/edit';
     Axios.get(uri).then((response) => {
     this.post = response.data;
     });
     
     },
     methods: {
     deletePost: function() {
     let uri = 'http://127.0.0.1:8000/api/'+this.$route.params.id;
     Axios.delete(uri, this.post).then((response) => {
     this.$router.push({name: 'Listposts'}) 
     
     })
     
     }
     }
    
     }
    </script>
    

    Creating Vue component for View post.

    Create a new file Viewpost.vue in resources/assets/js/components directory and put following code in it.

    Viewing record in Vue js

    //Viewpost.vue
    <template id="post">
     <div>
     <h2>{{ post.name }}</h2>
     <b>Description: </b>
     <div>{{ post.description }}</div>
     
     
     <br/>
     <span class="glyphicon glyphicon-arrow-left" aria-hidden="true"></span>
     <router-link v-bind:to="'/'">Back Post list</router-link>
     </div>
    </template>
    
    <script>
     export default {
     
     data: function () {
     return {post: {name: '', description: ''}}
     },
     created: function(){
     let uri = 'http://127.0.0.1:8000/api/'+this.$route.params.id;
     Axios.get(uri).then((response) => {
     this.post = response.data;
     });
     
     }
    
     }
    </script>
    

    Integrating Vue js with Laravel 5.5.

    Create a new file vueApp.blade.php in resources/views directory and add following Code in it.

     <!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>{{ config('app.name', 'Laravel') }}</title>
    
     <!-- Styles -->
     <link href="{{ asset('css/app.css') }}" rel="stylesheet">
    </head>
    <body>
    <div class="container">
     <header class="page-header">
     <div class="branding">
     <img src="https://vuejs.org/images/logo.png" alt="Logo" title="Home page" class="logo"/>
     <h1>Vue.js CRUD With Laravel 5.5 application</h1>
     </div>
     </header>
     
    </div>
    <section id="app">
    
    </section>
    <script>
     window.Laravel = <?php echo json_encode([
     'csrfToken' => csrf_token(),
     ]); ?>
    </script>
     <script src="{{ asset('js/app.js') }}"></script>
    </body>
    </html>

    Running our Application.

    Open your terminal and type below command to run the application

    php artisan serve
    

    Above command will start the server on port 8000. your app URL something looks like http://127.0.0.1:8000/ or
    http://localhost:8000/ copy the URL and open it in your favorite Browser.

    That's it, Thanks for reading please feel free to add a comment if you found any issue and trouble.

    Also, Complete source code of this tutorial is available on Github you can clone from below link https://github.com/sharadjaiswal1411/vuelaraveldemo

Please Login or Register to leave a response.

Related Articles

Laravel Tutorials

Laravel 5.5 Middleware complete Tutorial

In Laravel, you can think middleware as a system or tool that are used to filter all HTTP requests entering your application. Middleware works between request and response of our application. It sits ..

Laravel Tutorials

Laravel Pagination Ajax

Creating Ajax based pagination is Laravel 5.6. Ajax (Asynchronous JavaScript and XML) is a technique to update a specific part of webpage asynchronously without reloading the page. In this article, we..

Laravel Tutorials

Laravel Pagination

According to Wikipedia Pagination is a process of separating or dividing a document or digital contents into discrete pages. In Core PHP and other frameworks, paginating record is a painful task. Lara..