Building a basic SPA with Laravel and Vue Router

Written by on

In this article we're going to look at building a Single Page Application using Laravel and Vue Router. This article assumes a basic knowledge of Laravel, Vue and NPM. We’ll start with a basic installation of Laravel which is shipped with Vue.js as standard - for more information on installing Laravel please click here.

Once we have our fresh installation of Laravel we first need to install Vue Router, to do this open your terminal and cd to your fresh Laravel installation, then run the following commands:

npm install

Followed by:

npm install vue-router --save

Once Vue router is installed go to your app.js file in your text editor resources > assets >js > app.js and add the following lines:

import VueRouter from 'vue-router’;
Vue.use(VueRouter);

For ease now is probably a good time to open up a new tab in your terminal and run:

npm run watch

This will build a new app.js file in your public directory every time you you save your app.js resource file.

Next we need All of our web routes to be handled by Vue router, to keep this simple we’ll use the welcome.blade.php file provided by our Laravel install - navigate to routes > web.php in your text editor and replace the existing routes with:

Route::get('/{vue_capture?}', function() {
   return view(‘welcome’);
})->where('vue_capture', '[\/\w\.-]*');

Then to your resources > views > welcome.blade.php file go to the body tag and replace it’s content with:

<div id="app">
    <ul>
        <li><router-link to="/">Home</router-link></li>
        <li><router-link to="/page-1">Page 1</router-link></li>
        <li><router-link to="/page-2">Page 2</router-link></li>
    </ul>
    <router-view></router-view>
</div>
<script src="https://www.wearethreebears.co.uk/js/app.js"></script>

Now we need to create our 3 router link views - in resources > assets > js create a new directory called "views" and create 3 new files:

Home.vue

PageOne.vue

PageTwo.vue

Within each file add the following:

<template>
    <div class="content">
        *Name of view
    </div>
</template>

*Name of view should be something that easily lets you identify the view you are in, this is just to make testing nice and easy at this stage

Now we need to create our routes file to tell Vue what each router link should load into the router view. In resources > assets > js create a new file called routes.js and add the following:

import VueRouter from 'vue-router';

import Home from './views/Home.vue';
import PageOne from './views/PageOne.vue';
import PageTwo from './views/PageTwo.vue';

let routes = [
    {
        path: '/',
        name: 'home',
        component: Home
    },

    {
        path: '/page-1',
        name: 'pageOne',
        component: PageOne
    },

    {
        path: '/page-2',
        name: 'pageTwo',
        component: PageTwo
    },


];

const router = new VueRouter({
    routes: routes,
    mode: 'history'
});

export default router;

 Now back in our resources > assets > js > app.js file we need to reference our routes - Beneath our imports we’ll add:

import router from './routes';

 And change our app const to:

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

We'll add some very simple styling to our resources > views > welcome.blade.php file to make it easier to see what's going on in our SPA:

.content {
    display: block;
    width: 960px;
    margin: 20px auto;
    background: lightgrey;
    color: black;
    padding: 20px;
}

ul {
    width: 960px;
    margin: 20px auto;
}

li {
    display: inline-block;
}

a,
a:visited {
    color: grey;
}

a:hover,
a.router-link-exact-active {
    color: red;
}

 Our SPA should now look something like this:

Now by clicking through our links (Home, Page 1 and Page 2) at the top of our basic app, the content will change without the page refreshing.

And there we have it, our simple SPA built with Laravel and Vue Router - In future articles we'll expand on this very simple app adding offline capabilities and a native app like experience using a manifest file.

  • Laravel
  • Vue
  • Single Page Application
  • NPM