Using Vue in Laravel 5.3, with the Vue bootstrap and sample component

Posted on December 21, 2016 | By Matt Stauffer


In Laravel 5.3, it's easier than ever to write and use Vue components out of the box. This means 5.3 has a somewhat more opinionated default frontend stack than previous versions do. But never fear—it's easy to strip out the default components.

Let's explore 5.3's JavaScript stack together. Spin up a sample app using the Laravel installer (or, if you're like me, use Lambo) and open up the site in your favorite IDE.

The default package.json

First, take a look at our package.json:

{
  "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-14",
    "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"
  }
}

We're now pulling in Vue 2 and Vue Resource (which, by the way, is being retired soon and I believe will soon be replaced), and we still have jQuery and Sass and Lodash.

The default Gulp file

Now let's take a look at our Gulp (Elixir) file:

const elixir = require('laravel-elixir');

require('laravel-elixir-vue-2');

/*
 |--------------------------------------------------------------------------
 | Elixir Asset Management
 |--------------------------------------------------------------------------
 |
 | Elixir provides a clean, fluent API for defining some basic Gulp tasks
 | for your Laravel application. By default, we are compiling the Sass
 | file for your application as well as publishing vendor resources.
 |
 */

elixir((mix) => {
    mix.sass('app.scss')
       .webpack('app.js');
});

Nothing too different here, other than that we're pulling in Vue at the top and we're using Webpack to minify our scripts instead of Browserify.

Note: Taylor & Jeffrey just announced this week that the next version of Elixir will be based entirely on Webpack, not Gulp, and it'll be named Mix!

The default app.js file

So where do we go from here? Let's take a look at app.js (which is in resources/assets/js) to see what it's doing.

/**
 * First we will load all of this project's JavaScript dependencies which
 * include Vue and Vue Resource. This gives a great starting point for
 * building robust, powerful web applications using Vue and Laravel.
 */

require('./bootstrap');

/**
 * Next, we will create a fresh Vue application instance and attach it to
 * the page. Then, you may begin adding components to this application
 * or customize the JavaScript scaffolding to fit your unique needs.
 */

Vue.component('example', require('./components/Example.vue'));

const app = new Vue({
    el: '#app'
});

OK, so it looks like Laravel ships with a bootstrap.js file out of the box—we'll check that out in a second. Then we're pulling in an example Vue component, which we'll also take a look at. And it's binding our component to an element on our page with the ID of app.

Before we even look further, we can now assume that, if we compile this file and include it on our page, something like this would probably do something:

<html>
<head></head>
<body>
    <div id="app">
        <example></example>
    </div>
<script src="/js/app.js"></script>
</body>
</html>

The default bootstrap.js file

Let's figure out what it is actually going to do. First, we'll open up that bootstrap file, which is resources/assets/js/bootstrap.js:

window._ = require('lodash');

/**
 * We'll load jQuery and the Bootstrap jQuery plugin which provides support
 * for JavaScript based Bootstrap features such as modals and tabs. This
 * code may be modified to fit the specific needs of your application.
 */

window.$ = window.jQuery = require('jquery');
require('bootstrap-sass');

/**
 * Vue is a modern JavaScript library for building interactive web interfaces
 * using reactive data binding and reusable components. Vue's API is clean
 * and simple, leaving you to focus on building your next great project.
 */

window.Vue = require('vue');
require('vue-resource');

/**
 * We'll register a HTTP interceptor to attach the "CSRF" header to each of
 * the outgoing requests issued by this application. The CSRF middleware
 * included with Laravel will automatically verify the header's value.
 */

Vue.http.interceptors.push((request, next) => {
    request.headers.set('X-CSRF-TOKEN', Laravel.csrfToken);

    next();
});

/**
 * Echo exposes an expressive API for subscribing to channels and listening
 * for events that are broadcast by Laravel. Echo and event broadcasting
 * allows your team to easily build robust real-time web applications.
 */

// import Echo from "laravel-echo"

// window.Echo = new Echo({
//     broadcaster: 'pusher',
//     key: 'your-pusher-key'
// });

Alright, there's a lot more going on now! We've now pulled in jQuery, Bootstrap, Vue, and Vue-Resource. We're adding the CSRF token to the headers for Vue and Vue-Resource. And there's a placeholder to make it easy to start using Echo if we want.

The Example component

Let's take a look at this Example component in resources/assets/js/components/Example.vue:

<template>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <div class="panel panel-default">
                    <div class="panel-heading">Example Component</div>

                    <div class="panel-body">
                        I'm an example component!
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        mounted() {
            console.log('Component mounted.')
        }
    }
</script>

This is a Vueify-style Vue component that we can use as a sample to make our own components. You'll know it's working if you see the "Example Component" content on your screen.

Running Yarn and Gulp

So! Where do we go from here? Let's install our dependencies and run Elixir and then check the page out. We'll use Yarn (but if you don't have it, just run npm install instead):

yarn
gulp
gulp watch

Changes to Blade templates

How much work will we have to do to see if this actually works? Let's see what the 5.3 Blade templates look like. The default welcome.blade.php file doesn't reference these files at all, but the auth scaffolded files do, so run php artisan make:auth to publish them.

Now, we can take a look at our default resources/views/layouts.app.blade.php file:

<html>
... (header stuff)
    <script>
        window.Laravel = <?php echo json_encode([
            'csrfToken' => csrf_token(),
        ]); ?>
    </script>
</head>
<body>
    <div id="app">
        .. (lots of content)
    </div>

    <!-- Scripts -->
    <script src="/js/app.js"></script>
</body>
</html>

A few things of note here. First, the auth scaffolded files are pulling in /js/app.js, so they'll all have access to our Vue instance and all the dependencies we bound. Second, you can see that there's a base div with an ID of app, so that means we can use our Vue components anywhere within any of our templates and they'll be registered. And finally, there's a parent window.Laravel JavaScript object where you can set any useful information; with this sample, you could pull the CSRF token in any JavaScript now by simply referencing Laravel.csrfToken.

So. We've run Elixir, looked through all of our JavaScript files, and taken a look at the Blade templates that will be referencing them. Let's go see how it works!

In the browser

Since you're using Valet and likely spun this up with Lambo (right?) you can now visit these routes directly in your browser. I started this project with lambo blogpost, so I can now visit http://blogpost.dev/login to see what the Auth scaffold looks like.

Everything looks like it's working fine, I guess, so it's time for us to actually test that our Vue components are working correctly. Open up resources/views/auth/login.blade.php and add <example></example> anywhere within the content section.

Using the <example> component

Save, and refresh the page.

Showing the <example> component

There you go! You now have a fully functioning Vue stack with Bootstrap and jQuery and a sample, functioning, Vueify-style Vue component. Boom. Ready to go with almost no work.


Comments? I'm @stauffermatt on Twitter


Tags: laravel  •  laravel 5.3  •  vuejs  •  vueify  •  authorization