The user homepage will be a 3 columns layout. The first column will contain a text field for posting tweets and a nav menu. The second column will contain the user's timeline. The last column will display some users the user can follow. For now, we'll focus on the first two columns and we'll add the third column later on in the course.

For the first column, we create a UserSidebar component inside src/components/User and add the code below in it:

// src/components/User/UserSidebar.vue

<template>
    <div>
        <div class="ui attached segment">
            <form class="ui form">
                <div class="field">
                    <textarea name="tweet" v-model="tweet" rows="2" placeholder="Compose tweet"></textarea>
                </div>

                <button class="ui button fluid primary" :disabled="!isFormValid">Tweet</button>
            </form>
        </div>
        <div class="ui bottom attached menu">
            <router-link class="item" to="/">
                <i class="home icon"></i>
            </router-link>
            <router-link class="item" :to="`/${user.username}`">Profile</router-link>
            <router-link class="item" to="/settings/profile">Settings</router-link>
            <a class="item"><i class="sign out icon"></i></a>
        </div>
    </div>
</template>

<script>
    export default {
        name: 'UserSidebar',
        props: {
            user: {
                type: Object,
                required: true
            }
        },
        data () {
            return {
                tweet: ''
            }
        },
        computed: {
            isFormValid () {
                return !!this.tweet
            }
        }
    }
</script>

A simple text box for tweeting and a nav menu which contains links to the homepage, user profile, profile settings and to logout. The component accepts the authenticated user as props. We also add a simple input validator using a computed property. The tweet button will be disabled until a tweet is typed.

Table of Contents

    Next, let's create a Home component directly within the components folder. Paste the code below in it:

    // src/components/Home.vue
    
    <template>
        <div class="ui stackable grid vertically padded container">
            <div class="four wide column">
                <UserSidebar :user="user"/>
            </div>
            <div class="eight wide column">
                <div class="ui segment">
                    <h2 class="ui medium dividing header">Timeline</h2>
    
                    <Tweets
                        :tweets.sync="tweets"
                        :auth-user="user"
                    />
                </div>
            </div>
            <div class="four wide column"></div>
        </div>
    </template>

    We make use of both UserSidebar and Tweets components. We pass the necessary props to the components. Adding :tweets.sync on the Tweet component will allow us to perform a two way binding on the tweets props.

    Next, let's add the JavaScript section to the Home component. Still inside Home.vue, add the code below just after the template section:

    // src/components/Home.vue
    
    <script>
        import UserSidebar from '@/components/User/UserSidebar'
        import Tweets from '@/components/Tweet/Tweets'
    
        export default {
            name: 'Home',
            components: {
                UserSidebar,
                Tweets
            },
            data () {
                return {
                    user: '',
                    tweets: []
                }
            },
            beforeRouteEnter (to, from, next) {
                const token = localStorage.getItem('tweetr-token')
    
                return token ? next() : next('/login')
            },
            created () {
                this.fetchAuthenticatedUser()
                this.fetchUserTimeline()
            },
            methods: {
                fetchAuthenticatedUser () {
                    const token = localStorage.getItem('tweetr-token')
    
                    axios
                        .get('/account/me', {
                            headers: {
                                Authorization: `Bearer ${token}`
                            }
                        })
                        .then(response => {
                            this.user = response.data.data
                        })
                },
                fetchUserTimeline () {
                    const token = localStorage.getItem('tweetr-token')
    
                    axios
                        .get('/users/timeline', {
                            headers: {
                                Authorization: `Bearer ${token}`
                            }
                        })
                        .then(response => {
                            this.tweets = response.data.data.reverse()
                        })
                }
            }
        }
    </script>

    First we import the components used in the template, and then we define the user and tweets data. We also make sure only authenticated users can access this page. Within the created lifecycle hook, we called the fetchAuthenticatedUser and the fetchUserTimeline methods which fetches the authenticated user and his/her timeline respectively. The fetchUserTimeline method makes a GET request to the /users/timeline endpoint of our API passing to it the user's token. Notice we are reversing the tweets from the user's timeline so as to display the letest tweets first.

    Adding Home Route

    Open src/router/index.js, and add the code below to it:

    // src/router/index.js
    
    import Home from '@/components/Home'
    
    // add these inside the `routes` array
    {
        path: '/',
        component: Home
    },

    Visiting the / route, we should see the homepage as in the image below:

    Chimezie Enyinnaya

    16 posts

    Software Developer [PHP Laravel JavaScript NodeJS AdonisJS VueJS] | movie lover | run http://openlaravel.com