目錄
1. 功能簡介
2. 資料結構設計
3. 實作步驟
3.1 顯示評論
3.2 新增評論
3.3 展開和收縮評論
4. 总结
首頁 web前端 Vue.js Vue 中如何實現仿知乎的回答評論功能?

Vue 中如何實現仿知乎的回答評論功能?

Jun 25, 2023 pm 04:19 PM
vue 評論 回答

Vue是一款非常受歡迎的前端框架,它的靈活性和易用性使得它在web開發中有著廣泛的應用。知乎是一個非常流行的問答社區,它擁有龐大的用戶群和豐富的內容。在知乎中,回答下的評論功能是非常重要的。在本文中,我們將探討如何使用Vue來實現仿知乎的回答評論功能。

1. 功能簡介

在知乎中,使用者可以在回答下進行評論。評論可以形成一個樹狀結構,其中每個節點表示一個評論,節點之間有父子關係。使用者可以在每個節點下方加入自己的評論,同樣會形成樹狀結構。為了方便用戶查看,知乎還會展開和縮小評論。

以下是本文需要實作的功能清單:

  1. 使用者可以在回答下新增註解;
  2. 註解可以形成樹狀結構;
  3. #用戶可以在每個節點下面添加評論;
  4. 根據層級展示評論;
  5. 用戶可以展開和收縮評論。

2. 資料結構設計

在實作此功能之前,我們需要先設計資料結構。在知乎中,註解是樹狀結構,每個節點都有以下屬性:

  1. id: 節點的唯一識別碼;
  2. content: 節點的內容;
  3. author: 節點的作者;
  4. createTime: 節點建立時間;
  5. children: 子節點清單。

以下是該資料結構的定義:

interface Comment {
  id: string;
  content: string;
  author: string;
  createTime: number;
  children?: Comment[];
}
登入後複製

對於每個回答,我們需要一個評論清單。因為可能有多個回答,我們需要將這些評論清單放到一個物件中,這樣就可以透過回答的id來取得對應的評論清單。以下是該資料結構的定義:

interface CommentData {
  [answerId: string]: Comment[];
}
登入後複製

3. 實作步驟

3.1 顯示評論

我們需要先顯示評論清單。為了展示樹狀結構,我們可以使用遞歸組件。遞歸元件是指元件可以在自身模板中呼叫自身。

在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>
登入後複製

該元件會遞歸地渲染所有的子節點。

3.2 新增評論

在新增評論時,我們需要指定要新增到哪個節點下方。因此,我們需要為每個節點新增一個唯一識別碼。在本例中,我們使用UUID來產生唯一識別碼。同時,為了方便操作,我們也在每個節點中保存它所屬回答的id。

我們可以使用Vuex來管理狀態。新增評論的流程如下:

  1. 使用者輸入評論內容,並選擇要新增至哪個節點下方;
  2. 觸發Vuex的Action,向伺服器發送請求,在伺服器中新增評論記錄;
  3. 新增成功後,伺服器傳回新的評論記錄;
  4. 觸發Vuex的Mutation,將新的評論記錄新增至狀態。

在元件中,我們可以使用v-model指令來綁定使用者輸入的評論內容,並使用<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事件,以通知父元件刷新介面。

3.3 展開和收縮評論

展開和收縮評論是一項比較複雜的功能。需要記錄每個節點的展開狀態,並且能夠快速的取得所在節點和它的子節點。我們可以在Vuex的狀態中記錄每個節點的展開狀態。

展開與縮略評論的流程如下:

  1. 使用者點選展開或縮略;
  2. 觸發Vuex的Mutation,更新對應節點的展開狀態;
  3. 元件根據展開狀態,遞歸地渲染子節點。

這個功能我們需要寫一個遞迴元件。元件會根據節點是否展開來決定是否渲染子節點。在這個元件中,我們還需要編寫一個展開和收縮按鈕。以下是該元件的程式碼:

<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];
},
登入後複製

4. 总结

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

以上是Vue 中如何實現仿知乎的回答評論功能?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1653
14
CakePHP 教程
1413
52
Laravel 教程
1304
25
PHP教程
1251
29
C# 教程
1224
24
vue中怎麼用bootstrap vue中怎麼用bootstrap Apr 07, 2025 pm 11:33 PM

在 Vue.js 中使用 Bootstrap 分為五個步驟:安裝 Bootstrap。在 main.js 中導入 Bootstrap。直接在模板中使用 Bootstrap 組件。可選:自定義樣式。可選:使用插件。

vue怎麼給按鈕添加函數 vue怎麼給按鈕添加函數 Apr 08, 2025 am 08:51 AM

可以通過以下步驟為 Vue 按鈕添加函數:將 HTML 模板中的按鈕綁定到一個方法。在 Vue 實例中定義該方法並編寫函數邏輯。

vue中的watch怎麼用 vue中的watch怎麼用 Apr 07, 2025 pm 11:36 PM

Vue.js 中的 watch 選項允許開發者監聽特定數據的變化。當數據發生變化時,watch 會觸發一個回調函數,用於執行更新視圖或其他任務。其配置選項包括 immediate,用於指定是否立即執行回調,以及 deep,用於指定是否遞歸監聽對像或數組的更改。

vue多頁面開發是啥意思 vue多頁面開發是啥意思 Apr 07, 2025 pm 11:57 PM

Vue 多頁面開發是一種使用 Vue.js 框架構建應用程序的方法,其中應用程序被劃分為獨立的頁面:代碼維護性:將應用程序拆分為多個頁面可以使代碼更易於管理和維護。模塊化:每個頁面都可以作為獨立的模塊,便於重用和替換。路由簡單:頁面之間的導航可以通過簡單的路由配置來管理。 SEO 優化:每個頁面都有自己的 URL,這有助於搜索引擎優化。

vue返回上一頁的方法 vue返回上一頁的方法 Apr 07, 2025 pm 11:30 PM

Vue.js 返回上一頁有四種方法:$router.go(-1)$router.back()使用 &lt;router-link to=&quot;/&quot;&gt; 組件window.history.back(),方法選擇取決於場景。

vue.js怎麼引用js文件 vue.js怎麼引用js文件 Apr 07, 2025 pm 11:27 PM

在 Vue.js 中引用 JS 文件的方法有三種:直接使用 &lt;script&gt; 標籤指定路徑;利用 mounted() 生命週期鉤子動態導入;通過 Vuex 狀態管理庫進行導入。

vue遍歷怎麼用 vue遍歷怎麼用 Apr 07, 2025 pm 11:48 PM

Vue.js 遍歷數組和對像有三種常見方法:v-for 指令用於遍歷每個元素並渲染模板;v-bind 指令可與 v-for 一起使用,為每個元素動態設置屬性值;.map 方法可將數組元素轉換為新數組。

vue的div怎麼跳轉 vue的div怎麼跳轉 Apr 08, 2025 am 09:18 AM

Vue 中 div 元素跳轉的方法有兩種:使用 Vue Router,添加 router-link 組件。添加 @click 事件監聽器,調用 this.$router.push() 方法跳轉。

See all articles