Initial layout

Fourth post in the Mini Facebook Clone Series

Posted on November 21, 2016 in Facebook Clone, Laravel PHP Framework, vue.js

Layout considerations

To keep things relatively simpler. I've decided to leave the welcome.blade.php in the application. This page helps with authentication and the initial state of the application.

Layout modifications

In this step, we will look at modifying layouts/app.blade.php to remove our navigation and instead have it within a Vue component to enable us to manipulate information within our application.

Let's start by creating our Vue component. Within resources/js/components create a new folder called navigation. Within this new folder create a new Vue component called TopNav.vue. Open the newly created file and add the following:

<template>
    <p>TopNav</p>
</template>

<script>
    export default {

    }
</script>

This is the basic structure of a Vue component. You have your <template> tags and your <script> tags. You can also add <style> tags which allow you to create styles for your components. One thing to note about this is that <style> will publish the styles to all components. If you want to keep it within the scope of the current component add scoped to the tag like so: <style scoped>.

We now need to add this new component to our resources/js/app.js so we can use it within our application. Add it below our example component like so:

Vue.component('example', require('./components/Example.vue'));
Vue.component('top-nav', require('./components/navigation/TopNav.vue'));

If you now open resources/views/home.blade.php and add the new component within the @section('content') like below:

@extends('layouts.app')

@section('content')
    <top-nav></top-nav>
    <div class="container">
        <div class="row">
            <example></example>
        </div>
    </div>
@endsection

If all worked you should see something similar to the below (if you have any errors in your console log or the new component isn't showing, ensure you have either run gulp or gulp watch):

Image of new component

Let's now move our navigation from our resources/views/layouts/app.blade.php and into resources/assets/js/components/navigation/TopNav.vue. I have modified the navigation slightly so I have copied the code below:

<template>
    <nav class="navbar navbar-default navbar-static-top">
        <div class="container">
            <div class="navbar-header">

                <!-- Collapsed Hamburger -->
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#app-navbar-collapse">
                    <span class="sr-only">Toggle Navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>

                <!-- Branding Image -->
                <a class="navbar-brand" href="/home">
                    Mini-Facebook-Clone
                </a>
            </div>

            <div class="collapse navbar-collapse" id="app-navbar-collapse">
                <!-- Left Side Of Navbar -->
                <ul class="nav navbar-nav">
                     
                </ul>

                <!-- Right Side Of Navbar -->
                <ul class="nav navbar-nav navbar-right">
                    <li class="dropdown">
                        <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
                            TODO <span class="caret"></span>
                        </a>

                        <ul class="dropdown-menu" role="menu">
                            <li>
                                <a href="/logout"
                                   onclick="event.preventDefault();
                                                     document.getElementById('logout-form').submit();">
                                    Logout
                                </a>

                                <form id="logout-form" action="/logout" method="POST" style="display: none;">
                                    <input type="hidden" name="_token" v-model="csrfToken">
                                </form>
                            </li>
                        </ul>
                    </li>
                </ul>
            </div>
        </div>
    </nav>
</template>

<script>
    export default {
        data () {
            return {
                csrfToken: Laravel.csrfToken
            }
        }
    }
</script>

Things to note regarding the changes are as follows:

  1. I removed all of the original Laravel Blade syntaxes from URL's. For example, on the initial #navbar-brand anchor tag I removed the url() helper. The reason for this is that Vue also uses {{ }} as its view template binds. We will be updating the URL's in the future when we pull in Vue's router.
  2. Removed the authentication check. The reason for this is that users are not able to access the /home URI without previously being authenticated. We will also be bringing back the users name in the future, but for now, it is going to be TODO.
  3. Modified the logout form. Laravel recently made changes to the way a user is logged out. You can no longer make a GET request to /logout. This was to stop other sites potentially redirecting the user to the logout page. It now needs to be a POST request.

You should now see the following:

Image of new nav

Changing the example.

We are now going to change our Example.vue component and start with a very basic two column layout which we can improve on in the future if needed. We will have a small sidebar to the left and our content on the right. Let's first rename Example.vue to Home.vue. You will also need to change the line within app.js to reflect this change. Also don't forget to update your resources/views/home.blade.php to reflect the change from example to home. resources/views/home.blade.php should now look like:

@extends('layouts.app')

@section('content')
    <top-nav></top-nav>
    <home></home>
@endsection

Please also note I have removed the previous div tags.

Vue.component('home', require('./components/Home.vue'))

Now open Home.vue and add the following:

<template>
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-3">
                <side-nav></side-nav>
            </div>
            <div class="col-md-9">
                <timeline></timeline>
            </div>
        </div>
    </div>
</template>

<script>
    export default {

    }
</script>

We now need to create these two new components. Create resources/assets/js/components/navigation/SideNav.vue and resources/assets/js/components/Timeline.vue. Add both of these components to your app.js file like so:

Vue.component('side-nav', require('./components/navigation/SideNav.vue'));
Vue.component('timeline', require('./components/Timeline.vue'));

Now open SideNav.vue and add the following:

<template>
    <div class="panel panel-default">
        <div class="panel-heading">Side Navigation</div>
        <div class="panel-body">
            TODO
        </div>
    </div>
</template>

<script>
    export default {

    }
</script>

Now open Timeline.vue and add the following:

<template>
    <div class="panel panel-default">
        <div class="panel-heading">Timeline</div>
        <div class="panel-body">
            TODO
        </div>
    </div>
</template>

<script>
    export default {

    }
</script>

You should now see the following:

Image of new layout

I think that's it for this post. Next time we will look at pulling in the users information again and the beginnings of implementing Vuex into the mix.


comments powered by Disqus