A Quick Guide to Setting Up a Vue.js 2 and Laravel Homestead App

Hi there. Here are the steps I followed to speed up the process of building a Vue.js app powered by Laravel. The objective: Set up and run a new dev environment right away. I am using Homestead, which is a popular Vagrant box that comes with all you need to create modern PHP apps, so I will assume that you’ve already installed and set up Homestead on your local computer as well.

Without any further ado, let’s get started!

1. Add a New Entry in /etc/hosts

The 192.168.10.10 IP address is already set up in my Homestead/Homestead.yaml file by default (this is why I’m referring to it when adding an entry in my /etc/hosts file).

192.168.10.10   acme.local

2. Add a New Site to Your Homestead Environment

Edit the Homestead/Homestead.yaml file, and map the acme.local domain to your new website — be a little patient, we still have to create a new project in the next step.

sites:
    - map: acme.local
      to: /home/vagrant/projects/acme/public

3. Create a Laravel Project

First of all run the Homestead machine:

vagrant up

Wait a few seconds till it is up, then ssh and cd the projects folder:

vagrant ssh
cd projects

Create the project:

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

After completing this step you should be able to access your new website by typing http://acme.local in the address bar of your favourite browser.

Figure 1. Laravel welcome page

4. Install Laravel Mix

Laravel Mix is an awesome Webpack wrapper that makes your life easier as a developer, just install and forget about the nuts and bolts of Webpack.

cd acme
npm install

Assets are transpiled like this:

npm run dev

Or like this, if you want Webpack to dynamically recompile assets when detecting changes.

npm run watch

5. Set up a Minimal Vue App

Now replace the default original code in acme/resources/views/welcome.blade.php by this one:

<!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>Setting Up a Vue.js 2 App</title>
        <link href="{{ asset('css/app.css') }}" rel="stylesheet">
    </head>
    <body>
        <div class="container-fluid">
            <div class="col-md-12 text-center">
                <h1>Welcome to My Minimal App</h1>
            </div>
            <div id="app"></div>
        </div>
        <script src="{{ asset('js/app.js') }}"></script>
    </body>
</html>

As you see, the important thing is to make sure that our JavaScript application is being loaded:

<script src="{{ asset('js/app.js') }}"></script>

The next step is replacing the code in acme/resources/assets/js/app.js with this one:

require('./bootstrap');

import Vue from 'vue'
import Acme from './components/Acme'
import App from './components/App'

Vue.component('acme', Acme)

const app = new Vue({
    el: '#app',
    render:h => h(App)
})

Finally let’s write two simple single file components: App and Acme.

acme/resources/assets/js/components/App.vue

<template>
    <div class="col-md-6 col-md-offset-3">
        <acme></acme>
    </div>
</template>

<script>
import Acme from './Acme'

export default {
    components: {
        'Acme': Acme
    }
}
</script>

<style>
</style>

acme/resources/assets/js/components/Acme.vue

<template>
    <div class="panel panel-default">
        <div class="panel-heading">
            <h3 class="panel-title">Acme</h3>
        </div>
        <div class="panel-body">
            <p>Well done! You've set up your dev environment.</p>
            <button @click="onClick" class="btn">Click me</button>
        </div>
    </div>
</template>

<script>
export default {
    methods: {
        onClick(event) {
            alert("Thank you for clicking me.")
        }
    }
}
</script>

<style>
</style>

Don’t forget to transpile again:

npm run dev

Refresh the page and voila!

Figure 2. Well done! You’ve set up your dev environment.

That’s all for today! I hope you’ll find this tip helpful.