Task App with Laravel 5.3 and VueJS

In this tutorial we’re going to build a simple task app with Laravel 5.3 and Vuejs. You will learn:

  • How to get Vuejs up and running with Laravel 5.3 using Gulp

  • How to work with Vue Components (.vue)

  • How to make API calls with Vuejs

  • How to handle information coming from the server

  • The general workflow between Laravel 5.3 and Vuejs

I assume that you already know Laravel and the basics of Vuejs, especially the concept of components. If not, head to the documentation to get an idea of what we’re building here.

The full code is hosted on Github.


Create a new project:
laravel new laravel-vue-tasks

composer create-project laravel/laravel laravel-vue-tasks

In your terminal, go inside the project folder and install all dependencies:
cd laravel-vue-tasks
npm install

Here what’s happening:

  • npm install handles the installation of Vuejs and Gulp for us

  • Gulp will be used to run automated tasks, such compiling our assets

When it’s finished, just install bootstrap for some styling:
npm install bootstrap

The gulpfile.js will generate public/js/app.js from all the .js files in resources/assets/js. Thus, the app.js file is the only one that needs to be imported in the view. This also happens with the .sass files as public/css/app.css. Don’t worry much about it now, just be sure to run let this command be running in one of your terminal tabs:
gulp watch

Configuring the Database and Migrations

For this tutorial we’re going to use SQLite and only one table. In the .env file, change the following:


Then delete everything prefixed with DB_.

In app/config/database.php change:


Start your server and everything should be working:
php artisan serve

Next, create the following model with migration:
php artisan make:model Task -m

Just add the fillable property in app/Task.php:

Configure the migration in database/migrations/2016_08_30_234405_create_tasks_table.php as it follows:

Since the focus here is the workflow between Laravel 5.3 and Vuejs, let’s keep simple and just add a body attribute.

At last, run the migration:
php artisan migrate

Creating the API

Generally the route is prefix with ‘/api/’. Vuejs will make the calls through Ajax to the API, so there is no need to create a controller. Everything will be done in routes/api.php, except the process of showing our only view: that’s routes/web.php job.

In routes/web.php:

In routes/api.php:

The first thing you will notice is that all routes use the API middleware, which Laravel provide us out of the box. This also adds the prefix ‘/api/’ to each route entry. Next, we have the following:

  • GET route that returns all tasks from a descendant order

  • GET route that returns a task for the given ID

  • POST route responsible for creating a new task

  • PATCH route for updating a task

  • DELETE route to deleting a task

    Creating the View

    Let’s use the resources/views/welcome.blade.php:

  • We need the CSRF token to validate or request. For this, we add the lines 4 and 5.

  • The reference of the Javascript and CSS compiled files are made in lines 6 and 13.

  • Finally, add the components (that we going to create next) in lines 10 to 12.

Creating the Component

This is the most important part of the tutorial, but it’s not as hard as it sounds. Notice that the component must be saved with the .vue extension. So, create a file named Task.vue in resources/assets/js/components.

The next step is to register the component in resources/assets/js/app.js:

You will notice that Laravel, by default, already give us an Example.vue file. You can delete that as well the entry for the registration for this component. After that, be sure that Gulp compiled your assets running the gulp command in you terminal or just checking if the gulp watch command was successful.

The Vuejs components (.vue) are divided in two parts: the template and the script. The first holds the visual elements, while the later our logic.

In resources/assets/js/components/Tasks.vue:

Here is the explanation of the major concepts of Vuejs use in this template:

@submit.prevent – The @ symbol is equivalent to on:click. Using submit.prevent we prevent the default action, which is to submit the form for the URL in the action attribute. Instead, we send the form to the one of the defined functions.

edit ? updateTask(task.id) : createTask() – Here we have two functions in a ternary operation. If the edit property is true, send the submited data to updateTask(). If not, send do createTask(). Both these functions, as well the edit value, will be set in the script section below.

v-model=”task.body” – v-model allow us to bind a DOM element with a variable in the Javascript code. In this case, the property ‘body’ from the array ‘task’ is bounded to this input.

v-el:taskinput – v-el, on the other hand, allow us to give a name to the DOM element. With a name we can access the element pretty much like the $(‘#myelement’) in JQuery.

v-show=”!edit” – v-show enables the toggle property in the element. In this case, the element will be toggled if the edit variable is false. In the same way, by setting v-show=”edit” in the element below we indicate that we want to display the element when the edit variable is true.

v-for=”task in list” – v-for is the equivalent of @foreach in Blade Template. In other words, foreach task (element) in list ( total elements) do something. The list variable holds all the records from the database. We set it in the fetchTaskList() after getting the response from the API.

{{ task.body }} – We can access the properties inside the model using a dot. Just remember that it needs to be declared in the task variable in our script section.

@click=”showTask(task.id)” – Like the @submit, the @click listen for the on click event. In other words, the showTask method is triggered when the user clicks the button. The same occurs with the deleleTask method below.

Continuing in the same file, after closing the template tag, open a script section and type the following:

data – Here we define our variables.

edit – A boolean that indicates when we should display the edit task option or the create task option.

list – Holds the tasks elements retrieved from fetchTaskList.

task – Represents each element in the list. Each task retrieved from the database will be set through this variable.

ready – Do something when the application is ready. In this case, we only need to fetch the task list. We reference our own methods, as well the variables in the data section, through this.something.

methods – Where our methods are defined.

fetchTaskList – this.$http make an Ajax call to the server. First, we defined the method to be GET and the URL ‘api/tasks’. By using .then we are able to catch response and assign all the tasks retrieved from the API to the list variable. The v-for=”task in list” in the template takes care of rendering every task inside this list.

createTask – We’re also make an Ajax call, but this time with the POST method. The parameter this.task contains the information that the API expects to create the new task. In the line below we’re emptying the body of the task. This also empties the value of the input field since both are bounded. Next, the value of edit is set to false just to be sure that we display the New Task button. At last, this.fetchTaskList is called to fill the tasks into the page.

updateTask – This function is very similar to createTask, but here we send a PATCH request. The URL is concatenate with the ID of the task.

showTask – This function retrieve the task by ID and displays in the input field. This is possible because the ‘task’ variable and the input field are bounded. So, we just need to pass the response returned from the API to ‘task’ and Vuejs takes care of displaying it in the template.

deleteTask – We simply make a call to the API with the DELETE method and pass the task ID.


Laravel and Vuejs integration is great. While the first handle our back-end, the later ensures that the flow of data is smooth and the user experience is great. My favorite thing about Vuejs is that it didn’t enter in your way. Instead, it just does what is supposed to do: make the relationship between model and view dynamically. Besides, it’s really easy to learn when compared with other Javascript frameworks.

Put your thoughts on the comments below. See ya.

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInShare on Reddit

Published by


Developer with experience in PHP, Laravel, Ruby on Rails, and Android. B.S. in Information Technology.

23 thoughts on “Task App with Laravel 5.3 and VueJS”

  1. Hi, Thank you for taking time to do this. I followed through but unfortunately ended up with a blank screen. No errors from console, just a blank screen.
    It would be nice if you gave screenshots of your app in different stages. Most importantly,. the final app.

  2. Hi Feliciano!

    Thanks for this tutorial. I tried to get it done, but something is producing an error:

    When loading the page, no tasks are shown – even thou there are tasks created and correctly stored in database before.

    Chrome DEV-Tools console says:
    “[Vue warn]: Failed to resolve directive: el
    (found in component )”

    When creating a new Task via rendered Frontend, this error repeats with every keystroke. After hitting the “New Task” button, all tasks from database are getting listed correctly. This actions again produce another error-instances of the described above.

    My Setup is Ubuntu 16.04 Server, Laravel 5.3.21.

    Package.json content is:
    “private”: true,
    “scripts”: {
    “prod”: “gulp –production”,
    “dev”: “gulp watch”
    “devDependencies”: {
    “bootstrap-sass”: “^3.3.7”,
    “gulp”: “^3.9.1”,
    “jquery”: “^3.1.0”,
    “laravel-elixir”: “^6.0.0-11”,
    “laravel-elixir-vue-2”: “^0.2.0”,
    “laravel-elixir-webpack-official”: “^1.0.2”,
    “lodash”: “^4.16.2”,
    “vue”: “^2.0.1”,
    “vue-resource”: “^1.0.3”

    Maybe you have an idea, why my version (1:1 copy-paste version of your code) isn’t running without errors.

    Thanks a lot!


  3. Hey again,

    an addition after trying around.

    When removing ‘v-el:taskinput’ from the input-Element, the console error disappears.

    But i’m still getting no task listed when loading the page. Only after creating a task – or after other actions like ‘delete’ – the list is shown.

  4. Best guide, a question if work with two tables, one into other [example an dropdowlist or listbox with values into form], what would be the changes? of course my english is lousy.

  5. “This is the most important part of the tutorial, but it’s not as hard as it sounds. Notice that the component must be saved with the .vue extension. So, create a file named Task.vue in resources/assets/js/components.”

    should the file name “Tasks.vue” instead of “Task.vue”?

    I followed every steps of this tutorial, but got blank screen when i test it.. not sure where it went wrong.

  6. Hello sir, i have follow your tutorial and after i finish, gulp is working fine and everything else, but when i go to localhost:8000 i got a blank page with title “Laravel 5.3 with Vuejs”.

    i am missing something ???

  7. ERROR in ./~/vue-loader/lib/template-compiler.js?id=data-v-5b420922!./~/vue-loader/lib/selector.js?type=template&index=0!./resources/assets/js/components/Tasks.vue
    template syntax error Component template should contain exactly one root element:

    My Tasks
    New Task

    New Task
    Edit Task

    All Tasks

    {{ task.body }}

    If you are using v-if on multiple elements, use v-else-if to chain them instead.
    @ ./resources/assets/js/components/Tasks.vue 8:23-145
    @ ./resources/assets/js/app.js

  8. You get blank page because the Welcome.blade.php does not container id=”app” . As you might recall the app.js in the assets folder puts the tasks into the id=”app”


  9. Thanks a tone managed to make it work 🙂 this really help me understand how to setup vue in laravel 5.3 now i can fool around a bit with this. oh and i didn’t even use sqlite and left it on the default mysql and it worked.

  10. Login Form

    Login with email, enter your email address and we’ll send you a link to login.

    I have been through Insights Discovery

    Request Login Link

    export default{
    mounted() {

    data : function() {
    return {
    msg : []

    methods : {
    Login : function(e){
    url: “/api/login”,
    data: {email:$(“#email”).val()},
    success: function(result){

    jquery ajax doesn’t work.

  11. If you’re getting a blank screen do this:
    1. Edit welcome.blade.php and change
    2. Edit Tasks.vue and enclose all the elements within in
    like this

    If you get this error
    [Vue warn]: Failed to resolve directive: el
    It is because el was deprectated and now you shoul use ref=”taskinput” and look for the line
    this.$els.taskinput.focus() in the showTask method and change it
    by this.$refs.taskinput.focus
    I fixed this and the demo is working fine.

Leave a Reply

Your email address will not be published. Required fields are marked *