create account

Part 3 - Build Steem blockchain application with Vue.js: using Bootstrap, nav component, mixins, and first iteration of Posts component by aafeng

View this thread on: hive.blogpeakd.comecency.com
· @aafeng · (edited)
$28.64
Part 3 - Build Steem blockchain application with Vue.js: using Bootstrap, nav component, mixins, and first iteration of Posts component
![](https://cdn.steemitimages.com/DQmSnFb8dojCSjhpeXagQowTaqY11zrwfaxbXJsffKyYY6T/image.png)

## Repository

Vue.js: https://github.com/vuejs/vue

## What Will I Learn?

* How to use Bootstrap in Vue.js
* The nav component in Vue.js
* Abstract common functionalities into mixins
* Load posts from Steem blockchain into Posts component

## Requirements

* A Node.js environment (Ubuntu 18 + Node.js is used in this tutorial)
* Basic HTML/CSS/Javascript knowledge

## Difficulty

Basic level

## Tutorial contents

In last tutorial, you have learned Vue.js components, computed properties, and the build and deployment process for Vue.js application. In this tutorial, you will learn how to use Bootstrap in Vue.js, how to use nav component in Vue.js, use mixins to abstract common functionalities, and load post information from Steem blockchain into Posts component.

### The aim of this tutorial

As shown below, you will iterate your Vue.js application and add new functionalities: you will add three tabs, load posts from Steem blockchain, and use Bootstrap to control your Posts component layout.

![](https://cdn.steemitimages.com/DQmeCMduKmJCjc1opEBnaUJabE6SZ47Fg5hsptgahHGHk9r/image.png)

The live demo is here: https://aa-feng.github.io/

### Using Bootstrap in Vue.js

> Bootstrap 4 is the world's most popular framework for building responsive, mobile-first sites.

First, to make your Vue.js application responsive and control the layout of your components, you will learn how to use Bootstrap in your Vue.js application.

Run this command to install bootstrap-vue and bootstrap packages:

    npm i vue bootstrap-vue bootstrap --save

You also need to register BootstrapVue plugin in your application’s entry point, e.g. add the following code to main.js:

    import BootstrapVue from 'bootstrap-vue'
    Vue.use(BootstrapVue)

Also, import the CSS files:

    import 'bootstrap/dist/css/bootstrap.css'
    import 'bootstrap-vue/dist/bootstrap-vue.css'

Now, you are ready to use Bootstrap in your components! You can layout your POST component like this:

    <div class="row post">
      <div class="row post_header">
        <div class="col-sm-12">
          POST top bar
        </div>
      </div>

      <div class="row post_content">
        <div class="col-sm-2 col-xs-12 post_image">
          THUMBNAIL
        </div>
        <div  class="col-sm-10 col-xs-12 post_image">
          CONTENT
        </div>
      </div>
    </div>

It looks like:

![](https://cdn.steemitimages.com/DQmfDKB4VWDKbcWgywf2zb8Tsop6yVDY2PYxyCq4V3Z9fSr/image.png)

### The nav component in Vue.js

In previous tutorial, we only have a very basic navigation bar. Actually, Vue.js provides a nice navigation component called ‘nav’. You can change the navigation by changing the code in App.vue to:

    <template>
      <div id="app">
        <Profile></Profile>
        <b-nav tabs>
          <b-nav-item active><router-link to="/">Posts</router-link></b-nav-item>
          <b-nav-item><router-link to="/comments">Comments</router-link></b-nav-item>
          <b-nav-item><router-link to="/activities">Activities</router-link></b-nav-item>
        </b-nav>
        <router-view/>
      </div>
    </template>

Now you will be able to see the navigation bar as shown below:

![](https://cdn.steemitimages.com/DQmU25hBKGUsWZjkE3NSsfdmCbv2rdWHkeYoXEhgQoPb9Mf/image.png)

You may notice that some code refactoring has been done, e.g. the call to ‘Profile’ component has been moved to ‘App.vue’. The reason for that is because ‘Profile’ component is used by all three components, e.g. Posts, Comments, and Activities. Therefore, it is a better idea to call it in the parent component, e.g. in ‘App.vue’, rather than duplicate the calls in all these three components.

### mixins

> Mixins are a flexible way to distribute reusable functionalities for Vue components. A mixin object can contain any component options. When a component uses a mixin, all options in the mixin will be “mixed” into the component’s own options.

Since user information, e.g. username, reputation are used in all components, you don't want to duplicate your code across all these components. Mixins is the perfect way to abstract common functionalities into a single place. 

First, create file: src/components/mixins/user.js and add the following content:

    let steem = require('steem')

    export default {
      name: 'User',
      data () {
        return {
          username: 'aafeng', // default username
          profile: '', // Save user's jsonMetadata to profile
          userdata: '' // User's metadata
        }
      },
      created () {
        let names = [this.username]
        let currentComponent = this // Store this of current component (Profile) to currentComponent
        steem.api.getAccounts(names, function (err, result) { // retrieve data from Steem
          if (err) {
            console.log(err.stack)
          }
          currentComponent.userdata = result[0] // save the first user's data to userdata property
          var jsonMetadata = JSON.parse(result[0].json_metadata) // convert user's json_metadata to JSON
          currentComponent.profile = jsonMetadata.profile // save user's json_metadata to user's profile property
        })
      },
      computed: {
        voting_power () {
          return parseFloat(this.userdata.voting_power) / 100 // return a user friendly format of voting power
        },
        reputation () {
          return steem.formatter.reputation(this.userdata.reputation) // return a user friendly format of reputation
        }
      }
    }

All above code are moved from ‘Profile.vue’.  Then your ‘Profile.vue’ will be much simpler, e.g. the code will be:

    <script>
    import User from './mixins/user'

    export default {
      name: 'Profile',
      mixins: [User]
    }
    </script>

In the above code, you need to import the User from mixins then you need to declare you want to use ‘User’ mixin in your ‘Profile’ component. The template stays as same as the previous version. In other components, you just need to follow the same rule if you want to use ‘User’ mixin.

### First iteration of Posts component

To add posts information to Posts component, first you need to define a data attribute, e.g. posts, as shown below:

    data () {
      return {
        posts: [] // user's posts
      }
    }

Then, you can use Steem js to retrieve user’s posts from Steem blockchain, as shown below:

    created () {
      let postComponent = this 
      steem.api.getDiscussionsByAuthorBeforeDate(this.username, null, new Date().toISOString().split('.')[0], 10, function (err, result) {
        if (err) {
          console.log(err.stack)
        }
        postComponent.posts = result
      })
    }

You may notice that, for now, only a fixed number of posts are loaded, e.g. 10 latest posts are loaded.

For some information in the posts, e.g. the payouts (pending payouts / payouts), they might be used in other components, so it would be a good idea to define a new mixin, e.g. post mixin to include the common functionalities related to posts. You need to add a new file: src/components/mixins/posts.js with the following content:

    export default {
      name: 'Post',

      methods: {
        // return pending payout or paid awards
        payout (post) {
          if (post.pending_payout_value !== '0.000 SBD') { // If it’s pending payout
            return post.pending_payout_value.replace(' SBD', '')
          } else { // if past payout, use total_payout_value
            return post.total_payout_value.replace(' SBD', '')
          }
        },
        firstImage (post) { // return first image URL from page content
          const regex = /(https?:\/\/.*\.(?:png|jpg|gif))/g // For now only check jpg/png/gif images
          let img = regex.exec(post.body)
          if (img === undefined) {
            return ''
          }
          return img[0]
        }
      }
    }

In Posts component, both user and post mixins are needed, so declare them as below:

    mixins: [User, Post],

Now it is the time to modify the template in Post.vue:

    <div class="post_container">
      <div class="row post" v-for="post in posts" :key="post.post_id">
        <div class="row post_header">
          <div class="col-sm-12">
            {{username}}({{reputation}}) Category: {{ post.category }}
            Post time: {{ post.created }}
          </div>
        </div>
        <div class="row post_content">
          <div class="col-sm-2 col-xs-12 post_image">
            <img class="post_thumbnail" v-bind:src="firstImage(post)"/>
          </div>
          <div  class="col-sm-10 col-xs-12 post_image">
            <a v-bind:target="'_blank'" v-bind:href="'https://steemit.com'+post.url">{{ post.title }}</a><br/>

            Payout: ${{ payout(post) }}
            Votes: {{ post.active_votes.length }}
          </div>
        </div>
      </div>
    </div>

As you can see, all methods defined in user and post mixins can be used in the template directly. Now, each post shows like below:

![](https://cdn.steemitimages.com/DQmVQMXTw9d9wjBFn6s19g8sJ8jSFf5H1WZqiyvVNoTDBK4/image.png)

## Curriculum

This is the third tutorial. More interesting topics will be covered in the following tutorials!

### Previous tutorials

[Part 1 - Build Steem blockchain application with Vue.js: installation and first demo](/@aafeng/part-1-build-steem-blockchain-application-using-vue-js-installation-and-first-demo)
[Part 2 - Build Steem blockchain application with Vue.js: components, computed properties and build/deployment process](/@aafeng/part-2-build-steem-blockchain-application-using-vue-js-components-computed-properties-and-build-deployment-process)

## Proof of Work Done

Source code for this tutorial: https://github.com/aa-feng/VuejsTutorial/tree/t03.1

Master branch of the source code (will be updated with ongoing tutorials): https://github.com/aa-feng/VuejsTutorial

The live demo of latest iteration: https://aa-feng.github.io/
👍  , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , and 157 others
properties (23)
authoraafeng
permlinkpart-3-build-steem-blockchain-application-with-vue-js-using-bootstrap-mixins-and-first-iteration-of-posts-component
categoryutopian-io
json_metadata{"community":"steempeak","app":"steempeak/1.7.2b","format":"markdown","tags":["utopian-io","tutorials"],"users":["aafeng"],"links":["https://github.com/vuejs/vue","https://aa-feng.github.io/","/@aafeng/part-1-build-steem-blockchain-application-using-vue-js-installation-and-first-demo","/@aafeng/part-2-build-steem-blockchain-application-using-vue-js-components-computed-properties-and-build-deployment-process","https://github.com/aa-feng/VuejsTutorial/tree/t03.1","https://github.com/aa-feng/VuejsTutorial","https://aa-feng.github.io/"],"image":["https://cdn.steemitimages.com/DQmSnFb8dojCSjhpeXagQowTaqY11zrwfaxbXJsffKyYY6T/image.png","https://cdn.steemitimages.com/DQmeCMduKmJCjc1opEBnaUJabE6SZ47Fg5hsptgahHGHk9r/image.png","https://cdn.steemitimages.com/DQmfDKB4VWDKbcWgywf2zb8Tsop6yVDY2PYxyCq4V3Z9fSr/image.png","https://cdn.steemitimages.com/DQmU25hBKGUsWZjkE3NSsfdmCbv2rdWHkeYoXEhgQoPb9Mf/image.png","https://cdn.steemitimages.com/DQmVQMXTw9d9wjBFn6s19g8sJ8jSFf5H1WZqiyvVNoTDBK4/image.png"]}
created2019-02-23 22:22:15
last_update2019-02-25 22:18:42
depth0
children5
last_payout2019-03-02 22:22:15
cashout_time1969-12-31 23:59:59
total_payout_value21.530 HBD
curator_payout_value7.108 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length10,020
author_reputation554,723,599,569,926
root_title"Part 3 - Build Steem blockchain application with Vue.js: using Bootstrap, nav component, mixins, and first iteration of Posts component"
beneficiaries
0.
accountutopian.pay
weight500
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id80,301,046
net_rshares50,278,745,790,382
author_curate_reward""
vote details (221)
@steem-ua ·
$0.03
#### Hi @aafeng!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
**Feel free to join our [@steem-ua Discord server](https://discord.gg/KpBNYGz)**
👍  
properties (23)
authorsteem-ua
permlinkre-part-3-build-steem-blockchain-application-with-vue-js-using-bootstrap-mixins-and-first-iteration-of-posts-component-20190228t091021z
categoryutopian-io
json_metadata"{"app": "beem/0.20.18"}"
created2019-02-28 09:10:21
last_update2019-02-28 09:10:21
depth1
children0
last_payout2019-03-07 09:10:21
cashout_time1969-12-31 23:59:59
total_payout_value0.024 HBD
curator_payout_value0.007 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length285
author_reputation23,214,230,978,060
root_title"Part 3 - Build Steem blockchain application with Vue.js: using Bootstrap, nav component, mixins, and first iteration of Posts component"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id80,527,111
net_rshares54,023,205,915
author_curate_reward""
vote details (1)
@utopian-io ·
Hey, @aafeng!

**Thanks for contributing on Utopian**.
We’re already looking forward to your next contribution!

**Get higher incentives and support Utopian.io!**
 Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via [SteemPlus](https://chrome.google.com/webstore/detail/steemplus/mjbkjgcplmaneajhcbegoffkedeankaj?hl=en) or [Steeditor](https://steeditor.app)).

**Want to chat? Join us on Discord https://discord.gg/h52nFrV.**

<a href='https://steemconnect.com/sign/account-witness-vote?witness=utopian-io&approve=1'>Vote for Utopian Witness!</a>
properties (22)
authorutopian-io
permlinkre-part-3-build-steem-blockchain-application-with-vue-js-using-bootstrap-mixins-and-first-iteration-of-posts-component-20190228t120036z
categoryutopian-io
json_metadata"{"app": "beem/0.20.17"}"
created2019-02-28 12:00:39
last_update2019-02-28 12:00:39
depth1
children0
last_payout2019-03-07 12:00:39
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length588
author_reputation152,955,367,999,756
root_title"Part 3 - Build Steem blockchain application with Vue.js: using Bootstrap, nav component, mixins, and first iteration of Posts component"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id80,532,356
net_rshares0
@yokunjon · (edited)
$7.36
I thank you for your contribution. Here are my thoughts. Note that, my thoughts are my personal ideas on your post and they are not directly related to the review and scoring unlike the answers I gave in the questionnaire;

* **Language**

  * Usage of the first person makes tutorials harder to comprehend. If I were you, I would try my best to use the third person by changing the subjects of the sentences. I advise you to do that.
    For example;
    "The subject of the previous tutorial was the components of Vue.js, computed properties, building and deployment process of a Vue.js application."
    instead of
    "In last tutorial, you have learned Vue.js components, computed properties, and the build and deployment process for Vue.js application."

* **Content**

  * I appreciate the comments in your code blocks. (Thanks for listening @portugalcoin's suggestion.)

----
Your contribution has been evaluated according to [Utopian policies and guidelines](https://join.utopian.io/guidelines), as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, [click here](https://review.utopian.io/result/8/2-2-1-1-1-4-2-3-).

---- 
Need help? Chat with us on [Discord](https://discord.gg/uTyJkNm).

[[utopian-moderator]](https://join.utopian.io/)
👍  , , , , , , , , , , , , ,
properties (23)
authoryokunjon
permlinkre-aafeng-part-3-build-steem-blockchain-application-with-vue-js-using-bootstrap-mixins-and-first-iteration-of-posts-component-20190228t081911690z
categoryutopian-io
json_metadata{"tags":["utopian-io"],"users":["portugalcoin"],"links":["https://join.utopian.io/guidelines","https://review.utopian.io/result/8/2-2-1-1-1-4-2-3-","https://discord.gg/uTyJkNm","https://join.utopian.io/"],"app":"steemit/0.1"}
created2019-02-28 08:19:15
last_update2019-02-28 08:21:03
depth1
children2
last_payout2019-03-07 08:19:15
cashout_time1969-12-31 23:59:59
total_payout_value5.608 HBD
curator_payout_value1.751 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length1,334
author_reputation19,266,807,595,513
root_title"Part 3 - Build Steem blockchain application with Vue.js: using Bootstrap, nav component, mixins, and first iteration of Posts component"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id80,525,448
net_rshares12,272,090,713,155
author_curate_reward""
vote details (14)
@aafeng ·
Thank you for your suggestions.
👍  
properties (23)
authoraafeng
permlinkre-yokunjon-re-aafeng-part-3-build-steem-blockchain-application-with-vue-js-using-bootstrap-mixins-and-first-iteration-of-posts-component-20190228t193646183z
categoryutopian-io
json_metadata{"tags":["utopian-io"],"app":"steemit/0.1"}
created2019-02-28 19:36:45
last_update2019-02-28 19:36:45
depth2
children0
last_payout2019-03-07 19:36:45
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length31
author_reputation554,723,599,569,926
root_title"Part 3 - Build Steem blockchain application with Vue.js: using Bootstrap, nav component, mixins, and first iteration of Posts component"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id80,549,646
net_rshares19,226,523,646
author_curate_reward""
vote details (1)
@utopian-io ·
Thank you for your review, @yokunjon! Keep up the good work!
👍  
properties (23)
authorutopian-io
permlinkre-re-aafeng-part-3-build-steem-blockchain-application-with-vue-js-using-bootstrap-mixins-and-first-iteration-of-posts-component-20190228t081911690z-20190302t100932z
categoryutopian-io
json_metadata"{"app": "beem/0.20.17"}"
created2019-03-02 10:09:33
last_update2019-03-02 10:09:33
depth2
children0
last_payout2019-03-09 10:09:33
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length60
author_reputation152,955,367,999,756
root_title"Part 3 - Build Steem blockchain application with Vue.js: using Bootstrap, nav component, mixins, and first iteration of Posts component"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id80,620,820
net_rshares18,849,025,058
author_curate_reward""
vote details (1)