I am trying to implement nested comments in vue.js and nuxt.js.
- Each comment can have one or more children comments.
- Each child comment, can again, have one or more children comments.
- Unlimited levels of nested comments is possible.
As you can see in the diagram I have attached, I would like each comment to "know" (for the sake of simplicity, to display) the following information:
- The depth of the comment (I have this working already). Example, all of the "top-level" comments are at depth=0, all their children are at depth=1, and so on.
- The number of direct children
- the number of children (including nested children, unlimited levels deep)
I came across this question on StackOverflow but it doesn't quite do the trick. Or maybe I am doing something wrong.
In case you want to take a look at my (very messy) code, here it is. However, I'm willing to start over, so appreciate any pointers on how to pass the data up / down the chain of nested comments (vue components). Some sample code would be great.
components/PostComment.vue:
<template>
<div>
<div class="tw-flex tw-flex-wrap tw-justify-end">
<div :class="indent" class="tw-w-full tw-flex">
<div class="tw-font-bold tw-p-4 tw-border-gray-400 tw-border tw-rounded tw-text-right">
<div class="kb-card-section">
<div class="kb-card-section-content tw-flex tw-flex-wrap tw-items-center tw-text-left">
<div class="tw-flex tw-w-full">
<div class="tw-hidden md:tw-block md:tw-w-2/12 tw-text-right tw-my-auto">
<div class="tw-flex">
<p class="tw-w-full tw-text-xs tw-text-gray-600 tw-text-right">children: {{ numNestedChildComments }}, depth: {{depth}}</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="tw-w-full" v-if="commentData.nested_comments" v-for="nestedComment in commentData.nested_comments">
<post-comment
:commentData="nestedComment"
:depth="depth + 1"
:numChildCommentsOfParent=numNestedChildComments
/>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'post-comment', // necessary for recursive components / nested comments to work
props: {
depth: {
type: Number,
required: true
},
postAuthorData: {
type: Object,
required: true
},
commentAuthorData: {
type: Object,
required: true
},
commentData: {
type: Object,
required: true
},
numChildCommentsOfParent: {
type: Number,
required: true
},
},
data() {
return {
numNestedChildComments: this.numChildCommentsOfParent,
}
},
mounted() {
this.incrementNumParentComments();
},
methods: {
incrementNumParentComments() {
this.numNestedChildComments++;
this.$emit('incrementNumParentComments');
},
},
computed: {
indent() {
switch (this.depth) {
case 0:
return "tw-ml-0 tw-mt-1";
case 1:
return "tw-ml-4 tw-mt-1";
case 2:
return "tw-ml-8 tw-mt-1";
case 3:
default:
return "tw-ml-12 tw-mt-1";
}
},
},
}
</script>