Laravel, Vue and SPAs
Tags: laravel, vue, spa
Published: 2019-12-31 12:38:37

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`.
```shell
$ (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
```js
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.

```js
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.
```js
<template>
    <div>
        About
    </div>
</template>

<script>
export default {

}
</script>
```
And your `Home.vue` like

```js
<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.
```js
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
<?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.
```html
<!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.

```shell
$ (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:
```js
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:
```js
<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.
```shell
npm run dev && npm run watch
```
Then, open new tab in your terminal and run `artisan serve`
```shell
$ (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.
```shell
$ (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](https://github.com/irsyadadl/Laravel-Vue-and-SPAs).