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.
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 :
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
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
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<select>
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. <select>
元素来选择要添加到哪个节点下面。下面是一个组件的例子:
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
事件,以通知父组件刷新界面。
展开和收缩评论是一项比较复杂的功能。需要记录每个节点的展开状态,并能够快速的获取所在节点和它的子节点。我们可以在Vuex的状态中记录每个节点的展开状态。
展开和收缩评论的流程如下:
这个功能我们需要编写一个递归组件。组件会根据节点是否展开来决定是否渲染子节点。在该组件中,我们还需要编写一个展开和收缩按钮。下面是该组件的代码:
toggle(state, id) { state.expanded[id] = !state.expanded[id]; },
在该组件中,我们使用Vuex中的expanded
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]; },
本文介绍了如何使用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!