Contacts Manager – Laravel SPA

Single page application with vue, vue-router and vuex.

Basically, our entire app is a vue component with sub-components placed in <router-view></router-view>

In app.js we need to tell vue to use router and vuex.

import VueRouter from 'vue-router';
import Vuex from 'vuex';
import {routes} from './routes';
import StoreData from './store';

Vue.use(VueRouter);
Vue.use(Vuex);

const store = new Vuex.Store(StoreData);
const router = new VueRouter({
    routes,
    mode: 'history'
});
const app = new Vue({
    el: '#app',
    router,
    store,
    components: {
        MainApp
    }
});

You see that we have 2 new files: routes.js and store.js. Routes is the file where we define all our routes (wow, such a surprise 🙂 ). Basically, it is a js version of web.php. And store is the file that manages the common data of vue components.

routes.js

export const routes = [
    {
        path: '/',
        redirect: '/contacts'
    },
    {
        path: '/login',
        component: Login
    },
    {
        path: '/contacts',
        component: ContactContainer,
        meta: {
            requiresAuth: true
        },
        children: [
            {
                path: '/',
                component: ContactIndex
            },
            {
                path: 'create',
                component: ContactCreate
            },
            {
                path: ':id',
                component: ContactShow
            }
        ]
    }
];

store.js is quite big to put it here but here is the github link to it: link

It looks a lot like a vue component. You have

  • state: component data
  • getters: computed methods
  • mutations: every change to state data must be done through mutations
  • actions: these actions are dispatched by vue components to trigger changes in mutations

And let’s have a look on a component to see how is using the storage.

Here you have the Index.vue, list of all contacts.

<template>
    <div>
        <div class="row">
            <div class="col mb-2">
                <router-link to="/contacts/create" class="btn btn-primary">Create</router-link>
            </div>
        </div>
        <table class="table">
            <thead>
            <tr>
                <th>Name</th>
                <th>Email</th>
                <th>Phone</th>
                <th>Actions</th>
            </tr>
            </thead>
            <tbody>
            <template v-if="!contacts.length">
                <tr>
                    <td colspan="4" class="text-center">No Contacts Available</td>
                </tr>
            </template>
            <template v-else>
                <tr v-for="contact in contacts" :key="contact.id">
                    <td>{{ contact.name }}</td>
                    <td>{{ contact.email }}</td>
                    <td>{{ contact.phone }}</td>
                    <td><router-link :to="`/contacts/${contact.id}`">View</router-link></td>
                </tr>
            </template>
            </tbody>
        </table>
    </div>
</template>

<script>
    export default {
        name: 'index',
        mounted() {
          this.$store.dispatch('getContacts');
        },
        computed: {
            contacts() {
                return this.$store.getters.contacts;
            }
        }
    }
</script>

You see how we use this.$store.dispatch(‘getContacts’) to tell storage to get contacts. Now contacts are in storage and we get them with this.$store.getters.contacts.

Another thing, because we use router, links are defined in components with <router-link to=”/contacts” class=”btn btn-primary”>Contacts</router-link>

Here you have the link to github repository of this project.

https://github.com/andrei-cozma/wp-contacts-manager

Leave a Comment

Your email address will not be published. Required fields are marked *