Vue是一款非常受歡迎的前端框架,它的靈活性和易用性使得它在web開發中有著廣泛的應用。知乎是一個非常流行的問答社區,它擁有龐大的用戶群和豐富的內容。在知乎中,回答下的評論功能是非常重要的。在本文中,我們將探討如何使用Vue來實現仿知乎的回答評論功能。
在知乎中,使用者可以在回答下進行評論。評論可以形成一個樹狀結構,其中每個節點表示一個評論,節點之間有父子關係。使用者可以在每個節點下方加入自己的評論,同樣會形成樹狀結構。為了方便用戶查看,知乎還會展開和縮小評論。
以下是本文需要實作的功能清單:
在實作此功能之前,我們需要先設計資料結構。在知乎中,註解是樹狀結構,每個節點都有以下屬性:
以下是該資料結構的定義:
interface Comment { id: string; content: string; author: string; createTime: number; children?: Comment[]; }
對於每個回答,我們需要一個評論清單。因為可能有多個回答,我們需要將這些評論清單放到一個物件中,這樣就可以透過回答的id來取得對應的評論清單。以下是該資料結構的定義:
interface CommentData { [answerId: string]: Comment[]; }
我們需要先顯示評論清單。為了展示樹狀結構,我們可以使用遞歸組件。遞歸元件是指元件可以在自身模板中呼叫自身。
在Vue中,可以使用元件的name屬性來實作遞歸。下面是一個簡單的元件:
<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>
該元件會遞歸地渲染所有的子節點。
在新增評論時,我們需要指定要新增到哪個節點下方。因此,我們需要為每個節點新增一個唯一識別碼。在本例中,我們使用UUID來產生唯一識別碼。同時,為了方便操作,我們也在每個節點中保存它所屬回答的id。
我們可以使用Vuex來管理狀態。新增評論的流程如下:
在元件中,我們可以使用v-model指令來綁定使用者輸入的評論內容,並使用221f08282418e2996498697df914ce4e
元素來選擇要新增到哪個節點下面。以下是一個元件的範例:
<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
狀態來記錄每個節點是否展開。在元件的computed中,我們使用該狀態來判斷目前節點是否展開。在元件的methods中,我們使用Vuex的Mutation來更新展開狀態。
展開狀態的處理邏輯很簡單,我們只需要在Mutation中將對應的節點的展開狀態取反即可:
toggle(state, id) { state.expanded[id] = !state.expanded[id]; },
本文介绍了如何使用Vue实现仿知乎的回答评论功能,包括评论的树形结构、添加评论、展开和收缩评论。Vue的组件、状态管理和递归组件等特性,为实现该功能提供了非常便利的支持。如果您想尝试实现仿知乎的回答评论功能,本文提供了非常好的参考。
以上是Vue 中如何實現仿知乎的回答評論功能?的詳細內容。更多資訊請關注PHP中文網其他相關文章!