Laravel 5 VueJS Tutorial is today’s main topic. Laravel is PHP’s fastest growing Framework with its ease of use, scalability, and flexibility. VueJS is the fastest growing Front end Library in Javascript community. Laravel is providing VueJS support out of the box. So let us up and running with Laravel VueJS tutorial.

Summary

Laravel 5 and VueJS Tutorial will walk through the exercise of how you can set up the development environment with each other, and we are creating Simple CRUD Application.

Purpose

One possible reason I am writing this is showcase how Laravel PHP Framework and modern client-side Javascript frameworks (Vue.js) can all play nicely together.

Requirements

For learning Vue.js, I suggest to my this article Vuejs Tutorial With Example. It will guide you to learn fundamentals of Vue.js 2.0. If you want to know how a router works on Vue.js, then check out my this tutorial How To Use vue-router in VueJS.

We are using Laravel 5.4 and Vue.js 2.0. So technically It is the Laravel 5.4 Vue.js Tutorial.

If you want to learn Laravel CRUD example then check out my this tutorial Laravel 5.4 Crud Example From Scratch

Laravel 5 VueJS Tutorial

Step 1: Create the project Laravel Vue js Tutorial.

Type the following command in your terminal.

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

After installing the project, go to the project folder and type following command in your terminal.

npm install

It will install all the JavaScript dependencies regarding VueJS. It will install laravel-mix, which you can think of as kind of module bundle like webpack.

Now, setup a database in MySQL and also we need to configure in Laravel. So in your project root, there is a .env file, and in that file, you need to configure your username, DB name, and password. After configured, type following command in your terminal.

php artisan migrate

If you will navigate to resources >> assets >> js >> components, you will see the Example.vue component is there, so basically, Laravel provides VueJS support out of the box, though we can use other JS frameworks like ReactJS or AngularJS. This component is required in the outer JS file called app.js. This file will be compiled by Laravel Mix.

I have removed the comments provided by Laravel, so that app.js file will look like this.

// app.js require('./bootstrap'); window.Vue = require('vue'); Vue.component('example', require('./components/Example.vue')); const app = new Vue({ el: '#app' });

We need to install some other dependencies as well for the running VueJS library smoothly and also we need to use vue-router for routing our application.

npm install --save-dev vue-axios vue-loader vue-router vue-template-compiler

Step 2: Edit the default configuration.

We are going to change this file by the following code.

// app.js import Vue from 'vue'; import VueRouter from 'vue-router'; Vue.use(VueRouter); import VueAxios from 'vue-axios'; import axios from 'axios'; Vue.use(VueAxios, axios); const router = new VueRouter({ mode: 'history'}); new Vue(Vue.util.extend({ router })).$mount('#app');

Here, we have imported vue, vue-router and vue-axios, axios libraries for our application.

Created the router object and set the mode history so that we can get rid of the pound (#) on every route.

Now, switch to resources >> views >> welcome.blade.php file and replace the following code with that file.

// welcome.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"> <title>Laravel Vue CRUD Application</title> <link href="{{asset('css/app.css')}}" rel="stylesheet" type="text/css"> </head> <body> <div id="app"> </div> <script> window.Laravel = <?php echo json_encode([ 'csrfToken' => csrf_token(), ]); ?> </script> <script src="{{asset('js/app.js')}}"></script> </body> </html>

We need to create one Vue component inside resources >> assets >> js directory and call this component as an App.vue.

// App.vue <template> <div class="container"> <div> <transition name="fade"> <router-view></router-view> </transition> </div> </div> </template> <style> .fade-enter-active, .fade-leave-active { transition: opacity .5s } .fade-enter, .fade-leave-active { opacity: 0 } </style> <script> export default{ } </script>

This component will work as a container of our application. When routes of our VueJS application changes according to that different components will be rendered with in <router-view><router-view> tag.

We need to include this component into our app.js file and pass it to the Vue object while creating an instance.

// app.js import App from './App.vue'; new Vue(Vue.util.extend({ router }, App)).$mount('#app');

Go to the terminal and type following command.

npm run watch

If you see any error, please first check if there is dependency which needs to be installed at first place.

Step 3: Create routes with vue-router for our application.

In app.js file, we also include the Example.vue component because we are going to create routes for our application. So, first create an array of routes in app.js file.

// app.js const routes = [ { name: 'Example', path: '/', component: Example } ]; const router = new VueRouter({ mode: 'history', routes: routes}); new Vue(Vue.util.extend({ router }, App)).$mount('#app');

Here, I have created an array of routes and pass it to the router object. So, your whole app.js file will look like this.

// app.js import Vue from 'vue'; import VueRouter from 'vue-router'; Vue.use(VueRouter); import VueAxios from 'vue-axios'; import axios from 'axios'; Vue.use(VueAxios, axios); import App from './App.vue'; import Example from './components/Example.vue'; const routes = [ { name: 'Example', path: '/', component: Example } ]; const router = new VueRouter({ mode: 'history', routes: routes}); new Vue(Vue.util.extend({ router }, App)).$mount('#app');

Now, if everything is set up correctly then type the following command in your terminal.

php artisan serve

It will start the server on port 8000. So in chrome switch to this URL: http://localhost:8000

Step 4: Create Laravel Backend For Our Application.

Next step would be from moving VueJS to Laravel and create a backend for our project. We can use Web routes or API routes and for this project let us stick with web routes, so we need to put all of our routes in the routes >> web.php file.

First, we are going to perform CRUD operations on items. So first let us define the schema for it. Then we will create controller and routes.

Go to your command line and type following command. Make sure that, you are at the root of our project folder.

php artisan make:model Item -m

It will create two files.

Model file. Migration file.

Go to migration file in the database >> migrations >> create_items_table and copy the following code into it.

<?php // create_items_table use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateItemsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('items', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->integer('price'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('items'); } }

Go to the terminal and type the following command.

php artisan migrate

It creates the items table in the database. Also, one model file is created which is in the app folder.

It is time to create one resource controller called ItemController by the typing following command.

php artisan make:controller ItemController --resource

This ItemController contains all its methods of CRUD operations. We just need to put the code in it. I am right now putting the whole file with all the operations in it.

<?php // ItemController.php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Item; class ItemController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { $items = Item::all(); return response()->json($items); } /** * Show the form for creating a new resource. * * @return \Illuminate\Http\Response */ public function create() { // } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { $item = new Item([ 'name' => $request->get('name'), 'price' => $request->get('price') ]); $item->save(); return response()->json('Successfully added'); } /** * Display the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function show($id) { // } /** * Show the form for editing the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function edit($id) { $item = Item::find($id); return response()->json($item); } /** * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request * @param int $id * @return \Illuminate\Http\Response */ public function update(Request $request, $id) { $item = Item::find($id); $item->name = $request->get('name'); $item->price = $request->get('price'); $item->save(); return response()->json('Successfully Updated'); } /** * Remove the specified resource from storage. * * @param int $id * @return \Illuminate\Http\Response */ public function destroy($id) { $item = Item::find($id); $item->delete(); return response()->json('Successfully Deleted'); } }

We also need to create protected $fillable field in Item.php file otherwise ‘mass assignment exception‘ will be thrown.

<?php // Item.php namespace App; use Illuminate\Database\Eloquent\Model; class Item extends Model { protected $fillable = ['name', 'price']; }

The last step would be to register the routes in routes >> web.php file.

<?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'); }); Route::resource('items', 'ItemController');

Step 5: Make three components and register with App component.

All of our Backend is almost done. Now, if we switch to front end in Vue.js, we need to create three components, and then we include it in an app.js file to register the routes and is good to go.

Create following components inside resources >> assets >> js >> components.

CreateItem.vue EditItem.vue DisplayItem.vue

// CreateItem.vue <template> <div> <h1>Create An Item</h1> <form v-on:submit.prevent="addItem"> <div class="row"> <div class="col-md-6"> <div class="form-group"> <label>Item Name:</label> <input type="text" class="form-control" v-model="item.name"> </div> </div> </div> <div class="row"> <div class="col-md-6"> <div class="form-group"> <label>Item Price:</label> <input type="text" class="form-control col-md-6" v-model="item.price" /> </div> </div> </div><br /> <div class="form-group"> <button class="btn btn-primary">Add Item</button> </div> </form> </div> </template> <script> export default { data(){ return{ item:{} } }, methods: { addItem(){ let uri = 'http://localhost:8000/items'; this.axios.post(uri, this.item).then((response) => { this.$router.push({name: 'DisplayItem'}) }) } } } </script>

Here, I have defined the template which is basic Item creation form. In Javascript, I have to define item object and post method to post the data to the Laravel backend server.

Now, this file needs to be included in the app.js file to register the routes to be able to see the form.

Okay, now create one another component called DisplayItem.vue in the components folder.

// EditItem.vue <template> <div> <h1>Items</h1> <div class="row"> <div class="col-md-10"></div> <div class="col-md-2"> <router-link :to="{ name: 'CreateItem' }" class="btn btn-primary">Create Item</router-link> </div> </div><br /> <table class="table table-hover"> <thead> <tr> <td>ID</td> <td>Item Name</td> <td>Item Price</td> <td>Actions</td> </tr> </thead> <tbody> <tr v-for="item in items"> <td>{{ item.id }}</td> <td>{{ item.name }}</td> <td>{{ item.price }}</td> <td><router-link :to="{name: 'EditItem', params: { id: item.id }}" class="btn btn-primary">Edit</router-link></td> <td><button class="btn btn-danger" v-on:click="deleteItem(item.id)">Delete</button></td> </tr> </tbody> </table> </div> </template> <script> export default { data(){ return{ items: [] } }, created: function() { this.fetchItems(); }, methods: { fetchItems() { let uri = 'http://localhost:8000/items'; this.axios.get(uri).then((response) => { this.items = response.data; }); }, deleteItem(id) { let uri = `http://localhost:8000/items/${id}`; this.items.splice(id, 1); this.axios.delete(uri); } } } </script>

Here, I have written the component that displays the items in a tabular form and also, I have defined two other buttons one is for EditItem.vue and other is Delete function.

We also need to create the third and final component called EditItem.vue component.

// EditItem.vue <template> <div> <h1>Update Item</h1> <div class="row"> <div class="col-md-10"></div> <div class="col-md-2"><router-link :to="{ name: 'DisplayItem' }" class="btn btn-success">Return to Items</router-link></div> </div> <form v-on:submit.prevent="updateItem"> <div class="form-group"> <label>Item Name</label> <input type="text" class="form-control" v-model="item.name"> </div> <div class="form-group"> <label name="product_price">Item Price</label> <input type="text" class="form-control" v-model="item.price"> </div> <div class="form-group"> <button class="btn btn-primary">Update</button> </div> </form> </div> </template> <script> export default{ data(){ return{ item:{} } }, created: function(){ this.getItem(); }, methods: { getItem() { let uri = `http://localhost:8000/items/${this.$route.params.id}/edit`; this.axios.get(uri).then((response) => { this.item = response.data; }); }, updateItem() { let uri = 'http://localhost:8000/items/'+this.$route.params.id; this.axios.patch(uri, this.item).then((response) => { this.$router.push({name: 'DisplayItem'}); }); } } } </script>

Here, I have defined Update function with its POST request.

Now the last step is to include all this component into the app.js file.

We can remove now Example.vue component, as we do not need anymore.

// app.js import Vue from 'vue'; import VueRouter from 'vue-router'; Vue.use(VueRouter); import VueAxios from 'vue-axios'; import axios from 'axios'; Vue.use(VueAxios, axios); import App from './App.vue'; import CreateItem from './components/CreateItem.vue'; import DisplayItem from './components/DisplayItem.vue'; import EditItem from './components/EditItem.vue'; const routes = [ { name: 'CreateItem', path: '/items/create', component: CreateItem }, { name: 'DisplayItem', path: '/', component: DisplayItem }, { name: 'EditItem', path: '/edit/:id', component: EditItem } ]; const router = new VueRouter({ mode: 'history', routes: routes}); new Vue(Vue.util.extend({ router }, App)).$mount('#app');

Finally, go to the http://localhost:8000

If you have any data then the home screen will look like this. If you click on Create Item button.

If you will click on Edit button, then this will your page.

Download Project On Github

Steps :

Clone the repo. Run this command: composer update. Then, run this command to install npm dependencies: npm install Create a .env file and config the database. Run this command: php artisan migrate Then run this command: npm run dev php artisan serve. It will start the server at this URL: Next type this command:It will start the server at this URL: http://localhost:8000

Finally, our Laravel 5 VueJS Tutorial is over.

