Tutorial - Create a Steem post feed with Vue & DSteem
Repository
https://github.com/vuejs/vue
https://github.com/jnordberg/dsteem/
Outline
In this tutorials we’re going to make a website for a Steem Blog feed that loads post data from the Steem API. We’ll utilise Vue to handle templates and routing. We’ll look at Dsteem to retrieve data from the Steem blockchain.
This is a hands on project based tutorial.I prefer to make things rather than learn every possible function avaible. With that in mind this tutorial does not deep dive into specifcs but aims to hit the ground running. If you have questions about different aspects please feel free to ask in the comments. Enjoy.
Requirements
- A plain text editor (I use VS Code )
- Node.js Installed
Difficulty
Beginner - but not shy about digging into code. This tutorial is intended to be beginner friendly. If you’ve had some experience with Javascript and interacted with the command line before you should have no issues.
Learning Goals
- Setup a Vue.js Project with the command line
- Create and use custom component with Vue
- Create and use custom route within Vue
- Retrive data from the Steem Blockchain using Dsteem library
Check the Github commit history here to follow along with different steps and see the finished code.
Setup
First make sure you have Node.js installed and up to date.
Next lets install the latest version of Vue. You can use NPM or yarn for installing packages, from here I’ll be using yarn.
yarn global add @vue/cli
Once you’ve got Vue installed we can use it from the command line to create all of the boilerplate files we need to kickstart a Vue based website.
vue --version
Check you’re working with the latest version. For this tutorial I am work with vue version 3.2.1
Let’s go. We’ll run the vue create
command and will be prompted to select which features to install. Select ‘Manually select features’
vue create project-name
Make sure to select ‘router’. Navigate using the arrow keys and hitting spacebar to select.
Once setup. Navigate to the project and run the development server. Jumping the browser once it’s running to check out the standard Vue starter site.
cd project-name
yarn serve
Add Your First Component
Open the project in your text editor and familiarise yourself with the structure. The Vue app is built up of View and Component template files.
Create a new component within the components directory. src/components/SteemFeed.vue
. To start we’ll keep ip super simple, following the vue template structure and exporting the component in a script tag.
<template>
<div class="steemfeed">
<h1>Steem Feed</h1>
</div>
</template>
<script>
export default {
name: 'SteemFeed'
}
</script>
When using a component in a view there are three steps.
- Import the component
import SteemFeed from '@/components/SteemFeed.vue'
- Include the component in the exported view
components: {
HelloWorld,
SteemFeed // <- added here
}
- Include it where appropriate in your template
<div class="home">
<img alt="Vue logo" src="../assets/logo.png">
<SteemFeed/>
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
Now try removing the default HelloWorld component leaving only our custom Feed.
Step 2 - Load Steem Posts With Dsteem
Let’s make the component a little more exciting and include DSteem.
First add DSteem as a dependency to the project. (I’ve been having problems compiling the latest version of dsteem with vue. For simplify I’m going to set the version specifically)
yarn add [email protected]
Within our component include DSteem.
<script>
const dsteem = require('dsteem')
export default {
name: 'SteemFeed'
}
</script>
Next initialise dSteem and request data from the Database API. We’re going to hook into one of Vues actions. The created action. You can learn more about the ordering of Vue events here. For this simple app we’ll just run our DSteem code as the template is created.
export default {
name: 'SteemFeed',
created () {
const client = new dsteem.Client('https://api.steemit.com')
client.database.getDiscussions('blog', { tag: 'sambillingham', limit: 20 })
.then(result => {
console.log(result)
})
}
}
You can see we’re requesting 20 posts from a specific user and sending the result to the console. Now is a good time to fire up the server and check you are seeing the output in the console.
To make use of the data we can store i in the compontents data first and then use it in the template. Create a data function without the exported component. Set the value to null on creation, we’ll then update this with the STEEM response.
data () {
return {
posts: null
}
},
created () {
const client = new dsteem.Client('https://api.steemit.com')
client.database.getDiscussions('blog', { tag: 'sambillingham', limit: 20 })
.then(result => {
this.posts = result
})
}
Now we have access to this data from within our due template. Double curly brackets will render data {{ posts }}
. Try this and you’ll see the raw text output of the 20 item array.
In plain javascript or jQuery we would look over this data within Javascript and append a html item to the DOM. Within v we can use a vue directive to do this for us.
<main v-for="post in posts" :key="post.id">
<h2>{{post.title}}</h2>
</main>
This will output a heading tag for each of the items in the posts data array.All being well you’ll see a list of post titles on your homepage.
Step 3 - Vue Router
Let’s turn those title into link and setup a post page
The router.js file handles navigation for vue. Take a look at the default and you’ll see data for both the Home and About pages. Add a new route to the list.
{
path: '/:username/:permlink',
name: 'post',
component: SteemPost
}
Instead of using a set value. We’re going to use placeholders :username
and :permlink
. We don’t know what these values are and we don’t want to code them. Infact these values are what will let us load the correct data from the blockchain. These values act as parameters.
make sure to also include your component or view at the top of the router.js file e.g import SteemPost from './components/SteemPost.vue'
Set a name and component. Component can be a view or single Component. Let’s go ahead and create another component for the individual Steem Posts.
// src/componets/SteemPost.vue
<template>
<div>
<h1>STEEM Post</h1>
</div>
</template>
<script>
const dsteem = require('dsteem')
export default {
name: 'SteemPost',
data () {
return {
}
},
created () {
}
}
</script>
Now turn the titles into links to our SteemPost component
<h2>{{post.title}}</h2>
<router-link :to="`${post.author}/${post.permlink}`">
<h2>{{post.title}}</h2>
</router-link>
You can see a :to
property making use of the Steem data that is saveable within the loop.
The router link renders an an anchor tag but is setup within vue to automatically block page reloading and dynamically update the content while keeping history correct.
You should be able to navigate to individual posts with a correct url structure. You’ll only see the output of the SteemPost template though, which still looks the same for each post.
Step 4 - Steem Post Data
Pull individual post data for each post. We’ll work within the SteemPost.vue component.
created () {
const client = new dsteem.Client('https://api.steemit.com')
}
setup the esteem client
created () {
const client = new dsteem.Client('https://api.steemit.com')
client.call('condenser_api', 'get_content', [this.$route.params.username, this.$route.params.permlink])
.then(response => {
console.log(response)
})
}
Make a steem data request. You’ll notice I’m having to use the call method and the corresponding ‘get_content’ method directly. There is no helper for this yet (working on a PR for this).
The call to the STEEM API takes two parameters the username and permlink. We can access these from Vue’s this.$route
property. e.g this.$route.params.username
.
Add data attributes for the properties we’re interested in using within out view. The title and content.
data () {
return {
title: null,
content: null
}
},
mounted () {
const client = new dsteem.Client('https://api.steemit.com')
client.call('condenser_api', 'get_content', [this.$route.params.username, this.$route.params.permlink])
.then(response => {
this.title = response.title
this.content = response.body
})
}
From within our view. Make use of this new Data.
<template>
<div>
<h1>{{ title }}</h1>
<main>{{ content }}</main>
</div>
</template>
The content is currently the raw markdown stored on the blockchain. We can use ‘marked’ package to render the makrdown to html and include it within the view.
yarn add marked
- import marked from 'marked' within SteemPost.vue
- Update the function that stores the response data to make use of marked -
this.content = marked(response.body, { sanitize: true })
- use the
:v-html
directive to render html directly instead of data.<main v-html="content"></main>
Awesome! You should be seeing the post html instead of the raw marked down.
Step 5 - Tidy up CSS
You can add style directly within the vue components. Style as necessary.
main {
max-width: 700px;
margin: 0 auto;
text-align: left;
}
You might notice that you can’t style tags that that have been added with :v-thml
directive. You can use the Demo selector to target specific elements. e.g
*>>> img {
max-width: 100%;
}
Conclusion
You should have a working Vue website that display links to posts on the homepage and individual steem posts on a post page. I hope you’ve enjoyed this first look at Vue.
🚀View the finished Code on Github
If you have questions or any issues with the tutorial please reach out.
Thank you for your contribution @codewithsam.
We've been reviewing your tutorial and suggest the following points below:
The image with the data on the console is too small, we can not see the data. Try to put the image a little larger.
Nice work on the explanations of your code, although adding a bit more comments to the code can be helpful as well.
Your tutorial is excellent, thanks for your good work on developing this tutorial.
We are waiting for more of your 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? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]
Hey 👋thanks for taking the time to review the tutorial.
You're right the console screenshot it way to small! Doesn't help with the recent steemit.com image resolution downgrade too. I'll make sure to think about zooming in on these, I forget you can't easily do that on most Steem interfaces.
Code comments too 🙈oops! Can totally add more, would for sure be helpful when looking through the Github Repo. I think perhaps this would have been even better as a video tutorial. When working through projects with multiple files I think written tutorials sometimes struggle to show full files and enough comments/write up for each change. This was already 1800words and I felt I could have added a lot more detail.
Looking forward to adding more tutorials. Expect some more soon :)
Thank you for your review, @portugalcoin! Keep up the good work!
Thanks for this, that's exactly what I have been looking for! I will probably use React for my dApp though since I couldn't find a map plugin fit for my needs for Vue. How does dsteem compare to steem.js?
No worries. Hope it's helpful.
I've only just started playing with dsteem so can't give you a full comparison yet. The benchmarks I've seen show it to run significantly faster. Pretty sure It already has the same coverage for all of the API calls So i just need to learn the appropriate functions. So far so good.
Thanks for taking the time to create these tutorials especially during these difficult times. Im personally just learning javascript from you tube tutorials and doing OK with it so this has been favourited on partiko for the future! Best wishes and thanks again
Posted using Partiko Android
Yeah I guess there will be less excitement around these tutorials and crypto in general because of the markets. I still find it fun to make these and I hope people find them useful. Good to know you're learning javascript. If I can help with anything along the way let me know.
Ahh thank you very much. What Im finding (at 52!) is its not raw coding and syntax that gives me problems but the connecting everything together, the interfacing. Its all slow but sure and it helps I had a deepmIT background albeit 30 years ago!
Posted using Partiko Android
I totally understand that the interfacing might be daunting! There are so many different tools, programs and websites these days. You're kind of expected to just know how to use everything and it can be pretty difficult to get started. Slow and steady wins!
Congratulations @codewithsam! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :
Click here to view your Board of Honor
If you no longer want to receive notifications, reply to this comment with the word
STOP
Do not miss the last post from @steemitboard:
Congratulations @codewithsam! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :
Click here to view your Board of Honor
If you no longer want to receive notifications, reply to this comment with the word
STOP
Do not miss the last post from @steemitboard:
Hey, @codewithsam!
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!