Displaying threaded comments with VueJS

About six months ago, I wrote a how-to guide on displaying threaded comments with the WP REST API and Angular 1. In the past week or so, I’ve been learning VueJS and creating a starter theme with that.

Again, one of the things I had a hard time finding was tutorials on how to work with comments and VueJS. Fortunately, I had the code from the Angular starter theme that I was able to use. With a few small tweaks, I was able to get it working.

So to help others in a similar predicament, here’s a tutorial on showing threaded comments in VueJS.

Setup

So first things first. I’m going to make a couple of assumptions before we get going.

First, I’m going to assume that you know about the WP REST API and you know how to use it, at least on a basic level.

Second, I’m also going to assume that you are familiar with VueJS and know how it works and have most, if not all, of your components hooked up.

Now that that’s out of the way, there’s one thing we need to do in the functions.php file to get the comments. So place the following code into your functions.php file.

This will make sure that all of the comments and their data get sent to us when we grab a single post. Now, let’s get to the sorting.

Sorting

All right, now it’s time to get to the good stuff. So, to arrange the comments in the correct order, we’re going to need three functions. The first will get a comment in the list by its id. The second will get the depth of the comment. And the third will actually do the arranging.

Let’s start with the smallest one, grabbing a comment by the id. To do that, paste the following function into the methods section of your single post component.

The idea behind this function is simple. It accepts a parameter, the id of the comment, and goes through the list to find that comment and returns it. Simple enough.

Now let’s take it up another level, finding the depth of the comment. To do that, paste the following function into the methods section.

This takes in a comment, as well as the comment list, and checks to see if the comment is a child comment. It does that by seeing if the comment_parent attribute is zero or not. If not it finds the parent comment and runs the check again while increasing the depth number. And this continues until the attribute is zero.

Now, here’s where it all comes together. Finally, paste the following function into the methods section.

Let’s go through this by for loop. The first loop removes the unapproved comments. The second loop gets the comment depth for each comment. Then it runs through each comment to see which one has the deepest depth. We’ll use this value in the next loop.

The third loop starts at the deepest comment depth. Any comment that is at that depth is placed with its parent comment. Then the depth goes up one and the process repeats. Once this is done, all of the child comments are within their parent comments. The final loop goes through the top-level comments and removes the ones that are child comments to clean up the list.

So the heavy lifting is completely out of the way now; however, there are still a few more things we need to do before we can claim victory.

Implementation

So now we’re almost done with the comments. There’s just one more thing to do: creating a component to show the comments.

So first, create a new component and name it Comment. Before moving on, import the new component in your single post component. In the new VueJS file, place the following code.

This will display any information for a comment that you want to show. It also sets in motion the recursive call to this same component for any children comments.

And finally, place the following code in your single post component.

components: {
  'comment': Comment
}

The first section will go inside the template itself and the last section should go at the bottom of the component. This makes sure the single post component knows that it’s looking for the comment component in the imported file.

So now, you’re comments section should look a little something like this.

So there you have it. You now have a threaded comments section that looks like it would if it were a normal PHP template. And if want to look deeper into the code, here’s the VueJS starter theme with Foundation that I have up on GitHub.