目次
1. 機能の紹介
2. データ構造の設計
3. 実装手順
3.1 コメントの表示
3.2 コメントの追加
4. 总结
ホームページ ウェブフロントエンド Vue.js Zhihu のような回答とコメント機能を Vue に実装するにはどうすればよいですか?

Zhihu のような回答とコメント機能を Vue に実装するにはどうすればよいですか?

Jun 25, 2023 pm 04:19 PM
vue コメント 答え

Vue は非常に人気のあるフロントエンド フレームワークであり、その柔軟性と使いやすさにより、Web 開発で広く使用されています。 Zhihu は、大規模なユーザー ベースと豊富なコンテンツを備えた非常に人気のある Q&A コミュニティです。 Zhihuでは、回答の下にあるコメント機能が非常に重要です。この記事では、Vue を使用して Zhihu のような回答およびコメント機能を実装する方法を検討します。

1. 機能の紹介

Zhihu では、ユーザーは回答の下にコメントを付けることができます。コメントはツリー構造を形成できます。各ノードはコメントを表し、ノード間には親子関係があります。ユーザーは各ノードの下に独自のコメントを追加でき、ツリー構造も形成されます。ユーザーが閲覧しやすいように、Zhihu はコメントを拡大および縮小することもできます。

次は、この記事で実装する必要がある機能のリストです:

  1. ユーザーは回答の下にコメントを追加できます;
  2. コメントはツリー構造を形成できます;
  3. ユーザーは各ノードの下にコメントを追加できます;
  4. 階層に従ってコメントを表示します;
  5. ユーザーはコメントを展開および縮小できます。

2. データ構造の設計

この機能を実装する前に、まずデータ構造を設計する必要があります。 Zhihu では、コメントはツリー構造になっており、各ノードには次の属性があります:

  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 のアクションをトリガーし、サーバーにリクエストを送信し、サーバー レコードにコメントを追加します。
  3. 追加が成功すると、サーバーは新しいコメント レコードを返します。
  4. Vuex のミューテーションをトリガーして、新しいコメント レコードを状態に追加します。

コンポーネントでは、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 をコンポーネントのデータに双方向にバインドします。同時に、コンポーネントは comment 属性も受け取ります。この属性が存在する場合、コンポーネントが既存のコメントに追加されることを意味し、そうでない場合、コンポーネントは新しいコメントに追加されることを意味します答えの下にあります。

コンポーネントの created メソッドでは、コンポーネントによって追加されるコメントの子ノードのリストを取得します。現在のコンポーネントを既存のコメントに追加する場合は、その子ノード リストを使用します。それ以外の場合は、Vuex 状態から回答のコメント リストを取得します。

コンポーネントの addComment メソッドでは、Vuex のアクションを呼び出して、新しいコメント レコードをサーバーに追加できます。

async addComment() {
  const { content, parentId } = this;
  const answerId = this.answerId;
  await this.addComment({ answerId, parentId, content });
  this.$emit("added");
}
ログイン後にコピー

アクションが処理された後、## をトリガーします。 #added イベントは、親コンポーネントにインターフェースを更新するよう通知します。

3.3 コメントの展開と縮小

コメントの展開と縮小は、比較的複雑な機能です。各ノードの拡張状況を記録し、ノードとその子ノードを迅速に取得する必要があります。 Vuex 状態の各ノードの拡張ステータスを記録できます。

コメントの展開と縮小のプロセスは次のとおりです:

    ユーザーをクリックして展開または縮小します;
  1. Vuex のミューテーションをトリガーし、コメントの展開ステータスを更新します。対応するノード;
  2. コンポーネントは、展開された状態に基づいて子ノードを再帰的にレンダリングします。
この関数では、再帰コンポーネントを作成する必要があります。コンポーネントは、ノードが展開されているかどうかに基づいて、子ノードをレンダリングするかどうかを決定します。このコンポーネントでは、展開ボタンと折りたたみボタンも記述する必要があります。以下はコンポーネントのコードです:

<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 状態を使用して、各ノードが展開されているかどうかを記録します。計算コンポーネントでは、この状態を使用して現在のノードが展開されているかどうかを判断します。コンポーネントのメソッドでは、Vuex の Mutation を使用して展開された状態を更新します。

展開状態の処理ロジックは非常に単純で、Mutation:

で対応するノードの展開状態を反転するだけです。

toggle(state, id) {
  state.expanded[id] = !state.expanded[id];
},
ログイン後にコピー

4. 总结

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

以上がZhihu のような回答とコメント機能を Vue に実装するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

VueでBootstrapの使用方法 VueでBootstrapの使用方法 Apr 07, 2025 pm 11:33 PM

vue.jsでBootstrapを使用すると、5つのステップに分かれています。ブートストラップをインストールします。 main.jsにブートストラップをインポートしますブートストラップコンポーネントをテンプレートで直接使用します。オプション:カスタムスタイル。オプション:プラグインを使用します。

VUEのボタンに関数を追加する方法 VUEのボタンに関数を追加する方法 Apr 08, 2025 am 08:51 AM

HTMLテンプレートのボタンをメソッドにバインドすることにより、VUEボタンに関数を追加できます。 VUEインスタンスでメソッドを定義し、関数ロジックを書き込みます。

VueでWatchの使用方法 VueでWatchの使用方法 Apr 07, 2025 pm 11:36 PM

Vue.jsの監視オプションにより、開発者は特定のデータの変更をリッスンできます。データが変更されたら、Watchはコールバック関数をトリガーして更新ビューまたはその他のタスクを実行します。その構成オプションには、すぐにコールバックを実行するかどうかを指定する即時と、オブジェクトまたは配列の変更を再帰的に聴くかどうかを指定するDEEPが含まれます。

Vue Multi-Page開発とはどういう意味ですか? Vue Multi-Page開発とはどういう意味ですか? Apr 07, 2025 pm 11:57 PM

VUEマルチページ開発は、VUE.JSフレームワークを使用してアプリケーションを構築する方法です。アプリケーションは別々のページに分割されます。コードメンテナンス:アプリケーションを複数のページに分割すると、コードの管理とメンテナンスが容易になります。モジュール性:各ページは、簡単に再利用および交換するための別のモジュールとして使用できます。簡単なルーティング:ページ間のナビゲーションは、単純なルーティング構成を介して管理できます。 SEOの最適化:各ページには独自のURLがあり、SEOに役立ちます。

vue.jsでJSファイルを参照する方法 vue.jsでJSファイルを参照する方法 Apr 07, 2025 pm 11:27 PM

vue.jsでJSファイルを参照するには3つの方法があります。タグ;; mounted()ライフサイクルフックを使用した動的インポート。 Vuex State Management Libraryを介してインポートします。

Vueによる前のページに戻る方法 Vueによる前のページに戻る方法 Apr 07, 2025 pm 11:30 PM

vue.jsには、前のページに戻る4つの方法があります。$ router.go(-1)$ router.back()outes&lt; router-link to =&quot;/&quot; Component Window.history.back()、およびメソッド選択はシーンに依存します。

VUEトラバーサルの使用方法 VUEトラバーサルの使用方法 Apr 07, 2025 pm 11:48 PM

Vue.jsには配列とオブジェクトを通過するには3つの一般的な方法があります。V-Forディレクティブは、各要素をトラバースしてテンプレートをレンダリングするために使用されます。 V-BindディレクティブをV-Forで使用して、各要素の属性値を動的に設定できます。 .mapメソッドは、配列要素を新しい配列に変換できます。

VueのDivにジャンプする方法 VueのDivにジャンプする方法 Apr 08, 2025 am 09:18 AM

VUEにDIV要素をジャンプするには、VUEルーターを使用してルーターリンクコンポーネントを追加するには、2つの方法があります。 @clickイベントリスナーを追加して、これを呼び出します。$ router.push()メソッドをジャンプします。

See all articles