Part 4 - Build Steem blockchain application with Vue.js: dynamic route, and event handling
Repository
Vue.js: https://github.com/vuejs/vue
What Will I Learn?
- How to use dynamic route in Vue.js
- How to register event handler in Vue.js
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, how to use Bootstrap, navigation bar, and mixins were discussed. In this tutorial, the discussion will focus on how to use dynamic route to load other Steem user’s information, and how to use event handler to implement an infinite loading of user’s posts.
The aim of this tutorial
In the end of the tutorial, the new functionalities will be added to the Vue.js application:
First, by using dynamic route in Vue.js, this Vue.js application becomes more flexible, e.g. by adding a username to the end of the URL, that user’s information will be loaded.
Second, an infinite loading feature will be implemented by using Vue’s event handler.
The live demo is here: https://vuetutorials.aafeng.top
Using dynamic route in Vue.js
Update routes to accept username from URL
First, the routes defined in router/index.js need to be updated, e.g.
routes: [
{
path: '/:username/', // match path '/' to Posts component
name: 'Posts',
component: Posts
},
{
path: '/:username/comments/', // match path '/comments' to Comments component
name: 'Comments',
component: Comments
},
{
path: '/:username/activities/', // match path '/activities' to Activities component
name: 'Activities',
component: Activities
}
]
In the above code, :username will be used to store other username provided in the URL, e.g. if the URL is: https://YOUR_HOST/@utopian-io, then Vue.js will parse the URL and store ‘@utopian-io’ into ‘username’. To access the username passed via URL, the following expression can be used:
$route.params.username
Add a computed attribute to return appropriate username
A hardcoded username, e.g. ‘aafeng’ was used in previous tutorial, now it can be refactored to return appropriate username. For example, when username is not provided in the URL, a default username will be used. Otherwise the username provided in the URL will be used across the whole application. To do so, a computed username attribute can be defined as follows:
computed: {
username () {
const defaultUsername = 'aafeng' // default username
if ((typeof this.$route.params !== 'undefined') && (typeof this.$route.params.username !== 'undefined') && this.$route.params.username.startsWith('@')) {
return this.$route.params.username.substring(1, this.$route.params.username.length)
} else {
return defaultUsername
}
}
}
Access username in other components
Since username is needed while reading user’s posts in Posts component, so user mixin is need in Posts component:
mixins: [User, Post],
The navigation bar needs to be updated as well:
<b-nav tabs>
<b-nav-item active><router-link :to="'/@'+username">Posts</router-link></b-nav-item>
<b-nav-item><router-link :to="'/@'+username+'/comments'">Comments</router-link></b-nav-item>
<b-nav-item><router-link :to="'/@'+username+'/activities'">Activities</router-link></b-nav-item>
</b-nav>
Server configuration
As described in Vue.js documentation, server side configuration is needed. Otherwise a ‘404’ error will be issued when adding a username to the URL. Nginx is used in the demo site (https://vuetutorials.aafeng.top) and the Nginx configuration is:
location / {
try_files $uri $uri/ /index.html;
}
Register event handler in Vue.js
In previous tutorial, a fixed number of posts are loaded in the Posts component. An infinite load feature will be implemented in this tutorial, e.g. when user scroll down to reach the bottom of the current page, two more posts will be loaded and updated in the page. To achieve this, a new method called ‘scroll’ is added to Posts component:
scroll () {
let postComponent = this
window.onscroll = () => {
let bottomOfWindow = Math.round(document.documentElement.scrollTop + window.innerHeight + 5) >= document.documentElement.offsetHeight
if (bottomOfWindow) {
steem.api.getDiscussionsByAuthorBeforeDate(this.username, null, new Date().toISOString().split('.')[0], postComponent.posts.length + 2, function (err, result) {
if (err) {
console.log(err.stack)
}
postComponent.posts = result
})
}
}
}
In the above code, some calculation is needed to check if the bottom of the page is reached. When reached, a called is made to get current posts, plus two more posts. The posts attribute of Posts component is updated. Vue.js will monitor the changes to posts attribute and update the page automatically. Please note, ideally only two new posts need to be loaded and appended to the posts attributes. However, as stated in this issue, the beforeDate is not working. Since this issue is a bit off topic here, so the above code just simply load two more posts + currently loaded posts.
In addition, ‘scroll’ method must to be registered in mounted() method, as shown below:
mounted () {
this.scroll()
}
Curriculum
This is the 4th 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
Part 2 - Build Steem blockchain application with Vue.js: components, computed properties and build/deployment process
Part 3 - Build Steem blockchain application with Vue.js: using Bootstrap, nav component, mixins, and first iteration of Posts component
Proof of Work Done
Source code for this tutorial: https://github.com/aa-feng/VuejsTutorial/tree/t04
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://vuetutorials.aafeng.top
Thank you for your contribution @aafeng.
We've been reviewing your tutorial and suggest the following points below:
We suggest that in your tutorial put more images about what you are explaining.
Your tutorial is quite short for a good tutorial. We recommend you aim for capturing at least 2-3 concepts.
In the next tutorial put comments in the code sections. The comments help less experienced users better understand what they are developing.
The subject of your tutorial is interesting, but it is important to explain more features to make the tutorial more complete.
Looking forward to your upcoming tutorials.
Your contribution has been evaluated according to Utopian policies and 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.
Need help? Chat with us on Discord.
[utopian-moderator]
Thank you for your review, @portugalcoin! Keep up the good work!
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
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 or Steeditor).
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!