loading...
Cover image for Laravel, Vue and SPAs

Laravel, Vue and SPAs

irsyadadl profile image Irsyad A. Panjaitan Updated on ・3 min read

First of all, we need to setup laravel.

$ laravel new my-app

When it's done, cd in there and install all dependencies.

$ cd my-app
$ (my-app) > npm install

then let's install vue, vue router, and also vuex. I'm using npm, feel free to use yarn if you'are.

$ (my-app) > npm install vue vue-router vuex

After you've done all setup, now open your project in your editor text. Go to resources/js/ and let's make couple folder and file for store and router.

$ (my-app) > resources/js/
    ├── router
    │   └── index.js
    ├── store
    │   └── index.js

Then, open your app.js in resources/js/app.js and setup everything we need like

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

import store from "./store";
import routes from './router'

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

Now, let's open the index.js in router folder and setup the route, in this case, we just use two diffrent page home and about.

import Home from '../views/Home.vue'
import About from '../views/About.vue'

export default {
    mode: 'history',

    routes: [
        {
            path: '/',
            name: 'home',
            component: Home,
        },
        {
            path: '/about',
            name: 'about',
            component: About,
        }
    ]
}

You will suggest we will need the views folder and two file inside. So do this inside resources/js, now you will see your structur like this.

$ (my-app) > resources/js/
    ├── app.js
    ├── bootstrap.js
    ├── router
    │   └── index.js
    ├── store
    │   └── index.js
    └── views
        ├── About.vue
        └── Home.vue

Now open your About.vue and type just simple example.

<template>
    <div>
        About
    </div>
</template>

<script>
export default {

}
</script>

And your Home.vue like

<template>
    <div>
        Home
    </div>
</template>

<script>
export default {

}
</script>

Then, open your index.js in store folder and import vue & vuex, and use vuex as vue module like this.

import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);

export default new Vuex.Store({
    state: {},
    mutations: {},
    actions: {},
    modules: {}
})

And after you've done all thing, you can now open your web.php in routes folder. my-app/routes/web.php and just type one route for handling spa and 404 page like so:

<?php 

Route::view('/{any}', 'app')->where('any', '.*');

If we see all files in resources/views/, We know we have welcome.blade.php but just ignore it and let's make new file with name app.blade.php and you can remove welcome.blade.php if you want.

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Laracore</title>
</head>
<body class="antilaliased font-sans bg-gray-200">

    <main id="app">
        <navigation></navigation>
        <div class="py-5">
            <router-view></router-view>
        </div>
    </main>

    <script src="/js/min.js"></script>
</body>
</html>

If you see, I have include the navigation after main#app, and you will suggest we'll make new component for our navigation.
So know we need new folder in resources/js with name components, we will use navigation for our vue component in this case. Let's make new file with Navigation.vue in components folder, then your structur folder much like this.

$ (my-app) > resources/js/
    ├── app.js
    ├── bootstrap.js
    ├── components
    │   └── Navigation.vue
    ├── router
    │   └── index.js
    ├── store
    │   └── index.js
    └── views
        ├── About.vue
        └── Home.vue

Now open, app.js again, and include navigation component Vue.component('navigation', require('./components/Navigation.vue').default); and your app.js now like this:

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

import store from "./store";
import routes from './router'

Vue.component('navigation', require('./components/Navigation.vue').default);
const app = new Vue({
    el: '#app',
    store,
    router: new VueRouter(routes),
});

Now open components/Navigation.vue and type simple example like this:

<template>
    <div>
        <ul>
            <li>
                <router-link :to="{ name: 'home' }">Home</router-link>
            </li>
            <li>
                <router-link :to="{ name: 'about' }">About</router-link>
            </li>
        </ul>
    </div>
</template>

<script>
    export default {

    }
</script>

Now, open your terminal again, make two tab, one for watching for changes any file we have, and two for serving our laravel app.

First of all you have to compile your script like this.

npm run dev && npm run watch

Then, open new tab in your terminal and run artisan serve

$ (my-app) > php artisan serve

Open your browser http://127.0.0.1:8000 and that's it.

Now we are done. If you follow all stuffs we did, you will have structur in your resources like this.

$ (my-app) > resources
├── js
│   ├── app.js
│   ├── bootstrap.js
│   ├── components
│   │   └── Navigation.vue
│   ├── router
│   │   └── index.js
│   ├── store
│   │   └── index.js
│   └── views
│       ├── About.vue
│       └── Home.vue
└── views
    ├── app.blade.php

Now you can add package anything you want and import it in your app.js, think of it just like the Main.js file in vue-cli.

Get full source code in github.

Discussion

pic
Editor guide