Vue.js Nested List Rendering

The Task

Iterate over a list of blog posts from a WordPress.com blog and on clicking a button fetch a list of users that liked the post.

Display that list of users that liked the post nested within the blog post list.

A Little Background

I was preparing a basic demonstration of Vue.js at work, and part of that demo involved showing a large list of users. Each user block would have a button where we could then request a list of that user’s orders.

In short, I needed to render nested lists.

When I started to nest the list of orders within the list of users, I quickly realized my mistake.

The Problem

Any single nested list of ‘likes’ will appear in all post items. Obviously, we don’t want the same list of ‘likes’ appearing under each post; we need those ‘likes’ to be scoped to just their respective post.

The Solution

The solution was to create another component to hold each post in the post list. This way each list of users that liked the post would be properly scoped to just that post.

Resources

Getting Started

  • Download / clone / fork the repo, run NPM install.
  • Run ‘npm run dev’ from the root directory of the project. The project should open up automatically in your browser.
  • Posts.vue is where the action starts. Open it up and examine the code.

Master Branch (broken version)

The ‘master’ branch shows the broken code – the version of the project doesn’t render the users properly.

Posts.vue is rendering a list of posts and providing the click handler to fetch a secondary list of users that like each post.

Stripping out the post data being displayed, here are our lists:

<div class="card is-fullwidth" v-for="post in posts">
    <div class="card-content" v-for="like in likes">             
    </div>
</div>

If the problem isn’t obvious it will be when you load this up and click on the ‘GET LIKES’ link.

Fixed Branch

The ‘fixed’ branch demonstrates how I used a new Post component to scope the users list to the individual posts.

Now you need to look at Posts.vue and Post.vue.

It may seem tedious to break your UI into little components like this at first, but I have come to appreciate the simplicity of it all.

Posts.vue iterates over our list of posts as before, but now each post object is bound to Post.vue via props and rendered within that component.

Posts.vue

<div class="card is-fullwidth" v-for="post in posts">
    <Post :post="post"/>
</div>

Post.vue

export default {
    name: 'Post',
    props: ['post'],
    data() {
        return {
            likes: []
        }
    },
    methods: {
        getLikes
    }
}

With ‘post’ on the props array, we can access the post object in the template {{post.first_name}},

getLikes

Post.vue is now responsible for the getLikes() method, which makes more sense, and the resulting array of likes is scoped to that single post component.

Once this.likes is set to that data, the nested list of users that liked the post is rendered.

This setup makes it possible to scope each list of users that liked a post to the post itself. We can have any number of posts displaying their list of users and there’s no problem.

Challenge

Wire up a list of related posts (API Docs). and get a list of likes for those posts. It may be ugly, but practice with nesting all the information.


My name is Patrick O’Dacre, and I’m a software developer currently available for new opportunities.

It has been my pleasure to create ground-breaking e-commerce order systems, beautiful sales dashboards, and complex data grids with some incredibly talented people that made sure work never felt like work.

Some of my favorite tools include Vue.js, React.js, Node.js and Laravel, and I’m always excited to learn new things.

I love building great things with great people. Let’s build something great together.