Maison  >  Article  >  interface Web  >  Comment implémenter la fonction de réponse et de commentaire de type Zhihu dans Vue ?

Comment implémenter la fonction de réponse et de commentaire de type Zhihu dans Vue ?

PHPz
PHPzoriginal
2023-06-25 16:19:221457parcourir

Vue est un framework front-end très populaire. Sa flexibilité et sa facilité d'utilisation le rendent largement utilisé dans le développement web. Zhihu est une communauté de questions-réponses très populaire avec une large base d'utilisateurs et un contenu riche. Dans Zhihu, la fonction de commentaire sous les réponses est très importante. Dans cet article, nous explorerons comment utiliser Vue pour implémenter des fonctions de réponse et de commentaire de type Zhihu.

1. Introduction à la fonction

Dans Zhihu, les utilisateurs peuvent commenter sous les réponses. Les commentaires peuvent former une structure arborescente, dans laquelle chaque nœud représente un commentaire et il existe une relation parent-enfant entre les nœuds. Les utilisateurs peuvent ajouter leurs propres commentaires sous chaque nœud, qui formeront également une arborescence. Afin de faciliter la visualisation par les utilisateurs, Zhihu élargira et réduira également les commentaires.

Ce qui suit est une liste des fonctions qui doivent être implémentées dans cet article :

  1. Les utilisateurs peuvent ajouter des commentaires sous la réponse ; 🎜#Les commentaires peuvent former une structure en forme d'arbre ;
  2. Les utilisateurs peuvent ajouter des commentaires sous chaque nœud
  3. Afficher les commentaires selon la hiérarchie ;
  4. Les utilisateurs peuvent développer et contracter les commentaires.
  5. 2. Conception de la structure des données

Avant d'implémenter cette fonction, nous devons d'abord concevoir la structure des données. Dans Zhihu, les commentaires sont dans une arborescence, et chaque nœud possède les attributs suivants :

id : identifiant unique du nœud
  1. content : nœud Contenu ; ;
  2. author : l'auteur du nœud ;
  3. createTime : heure de création du nœud ;
  4. children : liste des nœuds enfants ;
  5. Voici la définition de la structure des données :
interface Comment {
  id: string;
  content: string;
  author: string;
  createTime: number;
  children?: Comment[];
}

Pour chaque réponse, nous avons besoin d'une liste de commentaires. Comme il peut y avoir plusieurs réponses, nous devons placer ces listes de commentaires dans un objet, afin que la liste de commentaires correspondante puisse être obtenue par l'identifiant de la réponse. Voici la définition de la structure des données :

interface CommentData {
  [answerId: string]: Comment[];
}

3. Étapes de mise en œuvre

3.1 Afficher les commentaires

Nous devons d'abord afficher la liste des commentaires . Pour afficher une arborescence, on peut utiliser des composants récursifs. Les composants récursifs signifient que le composant peut s'appeler dans son propre modèle.

Dans Vue, vous pouvez utiliser l'attribut name du composant pour implémenter la récursivité. Voici un composant simple :

<template>
  <div>
    <div>{{ comment.content }}</div>
    <div v-if="comment.children">
      <comment v-for="c in comment.children" :key="c.id" :comment="c" />
    </div>
  </div>
</template>

<script>
export default {
  name: "comment",
  props: {
    comment: {
      type: Object,
      required: true,
    },
  },
};
</script>

Ce composant restituera de manière récursive tous les nœuds enfants.

3.2 Ajouter un commentaire

Lors de l'ajout d'un commentaire, nous devons spécifier à quel nœud l'ajouter. Par conséquent, nous devons ajouter un identifiant unique à chaque nœud. Dans cet exemple, nous utilisons l'UUID pour générer un identifiant unique. Dans le même temps, pour la commodité de fonctionnement, nous enregistrons également l'identifiant de la réponse à laquelle il appartient dans chaque nœud.

Nous pouvons utiliser Vuex pour gérer l'état. Le processus d'ajout de commentaires est le suivant :

L'utilisateur saisit le contenu du commentaire et sélectionne le nœud auquel l'ajouter
  1. déclenche l'action de Vuex et envoie un demande au serveur. Ajoutez un enregistrement de commentaire au serveur ;
  2. Une fois l'ajout réussi, le serveur renvoie le nouvel enregistrement de commentaire
  3. déclenche la mutation de Vuex pour ajouter le nouveau ; enregistrement de commentaire au statut.
  4. Dans le composant, nous pouvons utiliser la directive v-model pour lier le contenu du commentaire saisi par l'utilisateur, et utiliser l'élément 221f08282418e2996498697df914ce4e pour sélectionnez quoi ajouter À quel nœud accéder. Voici un exemple de composant :
<template>
  <div>
    <div>
      <textarea v-model="content" />
    </div>
    <div>
      <select v-model="parentId">
        <option value="root">回答</option>
        <option :value="comment.id" v-for="comment in comments" :key="comment.id">
          {{ comment.content }}
        </option>
      </select>
    </div>
    <div>
      <button @click="addComment">添加评论</button>
    </div>
  </div>
</template>

<script>
import { mapActions } from "vuex";

export default {
  props: {
    answerId: {
      type: String,
      required: true,
    },
    comment: {
      type: Object,
      required: false,
      default: () => null,
    },
  },
  data() {
    return {
      content: "",
      parentId: "root",
      comments: [],
    };
  },
  created() {
    if (this.comment) {
      this.comments = this.comment.children || [];
    } else {
      this.comments = this.$store.state.comments[this.answerId] || [];
    }
  },
  methods: {
    ...mapActions("comments", ["addComment"]),
  },
};
</script>

Dans ce composant, nous lions de manière bidirectionnelle le contenu saisi par l'utilisateur et l'identifiant du nœud parent sélectionné aux données du composant. En même temps, le composant reçoit également un attribut comment Si cet attribut existe, cela signifie que le composant doit être ajouté à un commentaire existant sinon, le composant doit être ajouté à un nouveau ; commentaire sous la réponse. 221f08282418e2996498697df914ce4e元素来选择要添加到哪个节点下面。下面是一个组件的例子:

async addComment() {
  const { content, parentId } = this;
  const answerId = this.answerId;
  await this.addComment({ answerId, parentId, content });
  this.$emit("added");
}

在这个组件中,我们将用户输入的内容和选择的父节点id双向绑定到组件的data中。同时,该组件还接收一个comment属性,如果该属性存在,则表示该组件要添加到一个已有的评论下面;否则,该组件是要添加到回答下面的新评论。

在该组件的created方法中,我们检索该组件要添加的评论的子节点列表。如果当前组件是要添加到一个已有的评论下面,则使用它的子节点列表;否则,我们从Vuex的状态中获取所在回答的评论列表。

在组件的addComment方法中,我们可以调用Vuex的Action,来向服务器添加新的评论记录:

<template>
  <div>
    <div>
      <div>{{ comment.content }}</div>
      <div>
        <button @click="toggle"> {{ open ? "收起" : "展开" }} </button>
      </div>
    </div>
    <div v-if="open && comment.children">
      <comment v-for="subComment in comment.children" :key="subComment.id" :comment="subComment" />
    </div>
  </div>
</template>

<script>
export default {
  name: "comment",
  props: {
    comment: {
      type: Object,
      required: true,
    },
  },
  computed: {
    open() {
      return this.$store.state.expanded[this.comment.id];
    },
  },
  methods: {
    toggle() {
      this.$store.commit("toggle", this.comment.id);
    },
  },
};
</script>

在Action处理完毕后,我们触发added事件,以通知父组件刷新界面。

3.3 展开和收缩评论

展开和收缩评论是一项比较复杂的功能。需要记录每个节点的展开状态,并能够快速的获取所在节点和它的子节点。我们可以在Vuex的状态中记录每个节点的展开状态。

展开和收缩评论的流程如下:

  1. 用户点击展开或收缩;
  2. 触发Vuex的Mutation,更新对应节点的展开状态;
  3. 组件根据展开状态,递归地渲染子节点。

这个功能我们需要编写一个递归组件。组件会根据节点是否展开来决定是否渲染子节点。在该组件中,我们还需要编写一个展开和收缩按钮。下面是该组件的代码:

toggle(state, id) {
  state.expanded[id] = !state.expanded[id];
},

在该组件中,我们使用Vuex中的expanded

Dans la méthode created du composant, on récupère la liste des nœuds enfants des commentaires à ajouter par le composant. Si le composant actuel doit être ajouté à un commentaire existant, utilisez sa liste de nœuds enfants ; sinon, nous obtenons la liste de commentaires de la réponse de l'état Vuex.

Dans la méthode addComment du composant, nous pouvons appeler l'action de Vuex pour ajouter un nouvel enregistrement de commentaire au serveur : #🎜🎜#rrreee#🎜🎜#Traité en action après l'achèvement , nous déclenchons l'événement added pour notifier au composant parent d'actualiser l'interface. #🎜🎜##🎜🎜#3.3 Développer et réduire les commentaires#🎜🎜##🎜🎜#Agrandir et réduire les commentaires est une fonction relativement complexe. Il est nécessaire d'enregistrer l'état d'expansion de chaque nœud et d'obtenir rapidement le nœud et ses nœuds enfants. Nous pouvons enregistrer l'état d'expansion de chaque nœud dans l'état Vuex. #🎜🎜##🎜🎜#Le processus d'agrandissement et de réduction des commentaires est le suivant : #🎜🎜##🎜🎜##🎜🎜#L'utilisateur clique pour agrandir ou réduire #🎜🎜##🎜🎜# déclenche la mutation de Vuex ; et met à jour le nœud correspondant L'état d'expansion ; #🎜🎜##🎜🎜#Le composant restitue les nœuds enfants de manière récursive en fonction de l'état d'expansion. #🎜🎜##🎜🎜##🎜🎜#Pour cette fonction, nous devons écrire un composant récursif. Le composant décidera s'il faut restituer les nœuds enfants en fonction du fait que le nœud est développé ou non. Dans ce composant, nous devons également écrire un bouton de développement et de réduction. Voici le code de ce composant : #🎜🎜#rrreee#🎜🎜#Dans ce composant, nous utilisons l'état expanded dans Vuex pour enregistrer si chaque nœud est développé. Dans le composant calculé, nous utilisons cet état pour déterminer si le nœud actuel est développé. Dans les méthodes du composant, nous utilisons la mutation de Vuex pour mettre à jour l'état développé. #🎜🎜##🎜🎜#La logique de traitement de l'état d'expansion est très simple. Il suffit d'inverser l'état d'expansion du nœud correspondant dans Mutation : #🎜🎜#.
toggle(state, id) {
  state.expanded[id] = !state.expanded[id];
},

4. 总结

本文介绍了如何使用Vue实现仿知乎的回答评论功能,包括评论的树形结构、添加评论、展开和收缩评论。Vue的组件、状态管理和递归组件等特性,为实现该功能提供了非常便利的支持。如果您想尝试实现仿知乎的回答评论功能,本文提供了非常好的参考。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn