Vue ialah rangka kerja bahagian hadapan yang sangat popular. Fleksibiliti dan kemudahan penggunaannya menjadikannya digunakan secara meluas dalam pembangunan web. Zhihu ialah komuniti Soal Jawab yang sangat popular dengan pangkalan pengguna yang besar dan kandungan yang kaya. Di Zhihu, fungsi komen di bawah jawapan adalah sangat penting. Dalam artikel ini, kami akan meneroka cara menggunakan Vue untuk melaksanakan fungsi jawapan dan ulasan seperti Zhihu.
Dalam Zhihu, pengguna boleh mengulas di bawah jawapan. Komen boleh membentuk struktur pokok, di mana setiap nod mewakili ulasan dan terdapat hubungan ibu bapa-anak antara nod. Pengguna boleh menambah komen mereka sendiri di bawah setiap nod, yang juga akan membentuk struktur pokok. Untuk memudahkan pengguna melihat, Zhihu juga akan mengembangkan dan mengecilkan komen.
Berikut ialah senarai fungsi yang perlu dilaksanakan dalam artikel ini:
Sebelum melaksanakan fungsi ini, kita perlu mereka bentuk struktur data terlebih dahulu. Dalam Zhihu, ulasan berada dalam struktur pokok, dan setiap nod mempunyai atribut berikut:
Berikut ialah definisi struktur data:
interface Comment { id: string; content: string; author: string; createTime: number; children?: Comment[]; }
Untuk setiap jawapan, kami memerlukan senarai komen. Kerana mungkin terdapat berbilang jawapan, kita perlu meletakkan senarai komen ini ke dalam objek, supaya senarai komen yang sepadan boleh diperolehi oleh id jawapan. Berikut adalah definisi struktur data:
interface CommentData { [answerId: string]: Comment[]; }
Kita perlu paparkan senarai komen terlebih dahulu. Untuk memaparkan struktur pokok, kita boleh menggunakan komponen rekursif. Komponen rekursif bermaksud komponen itu boleh memanggil dirinya sendiri dalam templatnya sendiri.
Dalam Vue, anda boleh menggunakan atribut nama komponen untuk melaksanakan rekursi. Berikut ialah komponen mudah:
<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>
Komponen ini akan memaparkan semua nod anak secara rekursif.
Apabila menambah ulasan, kita perlu menentukan nod yang hendak ditambahkan. Oleh itu, kita perlu menambah pengecam unik pada setiap nod. Dalam contoh ini, kami menggunakan UUID untuk menjana pengecam unik. Pada masa yang sama, untuk kemudahan operasi, kami juga menyimpan id jawapan yang mana ia berada dalam setiap nod.
Kita boleh menggunakan Vuex untuk menguruskan keadaan. Proses menambah ulasan adalah seperti berikut:
Dalam komponen, kita boleh menggunakan arahan model v untuk mengikat kandungan ulasan yang dimasukkan oleh pengguna dan menggunakan elemen <select>
untuk memilih nod yang hendak ditambahkan. Berikut ialah contoh komponen: <select>
元素来选择要添加到哪个节点下面。下面是一个组件的例子:
<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>
在这个组件中,我们将用户输入的内容和选择的父节点id双向绑定到组件的data中。同时,该组件还接收一个comment
属性,如果该属性存在,则表示该组件要添加到一个已有的评论下面;否则,该组件是要添加到回答下面的新评论。
在该组件的created
方法中,我们检索该组件要添加的评论的子节点列表。如果当前组件是要添加到一个已有的评论下面,则使用它的子节点列表;否则,我们从Vuex的状态中获取所在回答的评论列表。
在组件的addComment
方法中,我们可以调用Vuex的Action,来向服务器添加新的评论记录:
async addComment() { const { content, parentId } = this; const answerId = this.answerId; await this.addComment({ answerId, parentId, content }); this.$emit("added"); }
在Action处理完毕后,我们触发added
事件,以通知父组件刷新界面。
展开和收缩评论是一项比较复杂的功能。需要记录每个节点的展开状态,并能够快速的获取所在节点和它的子节点。我们可以在Vuex的状态中记录每个节点的展开状态。
展开和收缩评论的流程如下:
这个功能我们需要编写一个递归组件。组件会根据节点是否展开来决定是否渲染子节点。在该组件中,我们还需要编写一个展开和收缩按钮。下面是该组件的代码:
<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>
在该组件中,我们使用Vuex中的expanded
toggle(state, id) { state.expanded[id] = !state.expanded[id]; },
comment
Jika atribut ini wujud, ini bermakna komponen itu akan ditambahkan pada ulasan sedia ada, jika tidak, komponen itu akan ditambah kepada yang baharu komen di bawah jawapan. Dalam kaedah dicipta
komponen, kami mendapatkan semula senarai nod anak bagi ulasan yang akan ditambahkan oleh komponen. Jika komponen semasa ingin ditambahkan pada ulasan sedia ada, gunakan senarai nod anak jika tidak, kami mendapat senarai komen jawapan daripada keadaan Vuex. 🎜🎜Dalam kaedah addComment
komponen, kami boleh memanggil Tindakan Vuex untuk menambah rekod ulasan baharu pada pelayan: 🎜rrreee🎜Selepas Tindakan diproses, kami mencetuskan expanded
dalam Vuex untuk merekodkan sama ada setiap nod dikembangkan. Dalam komponen yang dikira, kami menggunakan keadaan ini untuk menentukan sama ada nod semasa dikembangkan. Dalam kaedah komponen, kami menggunakan Mutasi Vuex untuk mengemas kini keadaan dikembangkan. 🎜🎜Logik pemprosesan keadaan pengembangan adalah sangat mudah Kita hanya perlu menyongsangkan keadaan pengembangan nod yang sepadan dalam Mutasi: 🎜toggle(state, id) { state.expanded[id] = !state.expanded[id]; },
本文介绍了如何使用Vue实现仿知乎的回答评论功能,包括评论的树形结构、添加评论、展开和收缩评论。Vue的组件、状态管理和递归组件等特性,为实现该功能提供了非常便利的支持。如果您想尝试实现仿知乎的回答评论功能,本文提供了非常好的参考。
Atas ialah kandungan terperinci Bagaimana untuk melaksanakan fungsi jawapan dan komen seperti Zhihu dalam Vue?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!