Rumah  >  Artikel  >  hujung hadapan web  >  Bagaimana untuk melaksanakan fungsi jawapan dan komen seperti Zhihu dalam Vue?

Bagaimana untuk melaksanakan fungsi jawapan dan komen seperti Zhihu dalam Vue?

PHPz
PHPzasal
2023-06-25 16:19:221523semak imbas

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.

1. Pengenalan fungsi

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:

  1. Pengguna boleh menambah komen di bawah jawapan
  2. Komen boleh membentuk struktur pokok
  3. Pengguna boleh menambah komen di bawah setiap nod
  4. ; komen mengikut tahap;
  5. Pengguna boleh mengembangkan dan mengecilkan komen.

2. Reka bentuk struktur data

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:

  1. id: pengecam unik nod
  2. kandungan: kandungan nod
  3. pengarang: pengarang nod;
  4. createTime: Masa penciptaan nod;
  5. kanak-kanak: senarai nod anak.

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[];
}

3 Langkah pelaksanaan

3.1 Paparkan komen

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.

3.2 Tambah ulasan

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:

  1. Pengguna memasukkan kandungan ulasan dan memilih nod yang hendak ditambahkan
  2. mencetuskan Tindakan Vuex, menghantar permintaan ke pelayan dan menambah rekod ulasan dalam pelayan;
  3. Selepas penambahan berjaya, pelayan mengembalikan rekod ulasan baharu;
  4. mencetuskan Mutasi Vuex untuk menambah rekod ulasan baharu ke negeri ini.

Dalam komponen, kita boleh menggunakan arahan model v untuk mengikat kandungan ulasan yang dimasukkan oleh pengguna dan menggunakan elemen 221f08282418e2996498697df914ce4e untuk memilih nod yang hendak ditambahkan. Berikut ialah contoh komponen: 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事件,以通知父组件刷新界面。

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

toggle(state, id) {
  state.expanded[id] = !state.expanded[id];
},

Dalam komponen ini, kami mengikat secara dwiarah kandungan yang dimasukkan oleh pengguna dan id nod induk yang dipilih pada data komponen. Pada masa yang sama, komponen juga menerima atribut 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 ditambahAcara untuk memberitahu komponen induk untuk menyegarkan antara muka. 🎜🎜3.3 Kembangkan dan kecilkan ulasan🎜🎜Meluaskan dan mengecilkan ulasan ialah fungsi yang agak kompleks. Ia adalah perlu untuk merekodkan status pengembangan setiap nod dan mendapatkan nod dan nod anak dengan cepat. Kita boleh merekodkan status pengembangan setiap nod dalam keadaan Vuex. 🎜🎜Proses mengembang dan mengecilkan komen adalah seperti berikut: 🎜🎜🎜Pengguna mengklik untuk mengembangkan atau mengecil; 🎜🎜mencetuskan Mutasi Vuex untuk mengemas kini status pengembangan nod yang sepadan 🎜🎜menghasilkan komponen rekursif; status pengembangan. 🎜🎜🎜Untuk fungsi ini kita perlu menulis komponen rekursif. Komponen akan memutuskan sama ada untuk membuat nod anak berdasarkan sama ada nod itu dikembangkan. Dalam komponen ini, kita juga perlu menulis butang kembangkan dan runtuh. Berikut ialah kod komponen: 🎜rrreee🎜Dalam komponen ini, kami menggunakan keadaan 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];
},

4. 总结

本文介绍了如何使用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!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn