在列表中添加/删除项目后,请使用onSnapshot正确渲染任务列表 无法正常工作

我在做什么

我正在使用vue和firestore制作一个简单的任务组织应用程序。 到目前为止,我做了5个功能。

  1. 登录
  2. 注册
  3. 获取并呈现任务列表
  4. 添加/删除任务
  5. [不起作用!]实时呈现任务列表中的任何更改

无法正常工作

它从Firestore获取并加载数组数据并实时渲染,但是渲染不正确


问题详细信息

由于在列表中添加或删除任务而更新列表时,此问题变得明显。

请检查图像以更清晰地查看问题。

Screenshots of issue


我尝试过的

  • 通过刷新页面来解决,但失去了实时更新的意义。
  • 看到设置Vue()/新Vue()可以解决但没有解决的地方。 (或者更像是我太初学者,无法理解该概念以应用它...)

我很可能不了解背后的真正问题是什么...因此,如果有人可以指出我的真正问题,那将是很好的。因此,期待听到您的想法!

代码

主要有两个文件负责呈现任务列表。

  1. projectList.vue:在哪里获取和加载数组数据并呈现任务列表
  2. projectCard.vue:我在其中插入projectList.vue的每个任务的数据以创建列表。

(我还将添加用于添加项目的脚本;以防万一,请添加addProject.js。)


projectList.vue:获取,加载,渲染任务列表

<template>
  <div class="projectList">
    <button class="home-buttons" @click="newProject">Add project</button>
    <div v-if="createNew">
      <projectAdd/>
    </div>
    <div v-show="loading">
      <Loader/>
    </div>
    <div v-show="!loading">

      <!--03 Pass array data to projectCard.vue then render the list of entries-->
      <projectCard v-for="project in projects" :key="project.id" :project="project"/>

    </div>
    <p v-show="noproject">There is no project</p>
  </div>

</template>

<script>
import firebase from '@/firebase/firestore';
import Loader from '@/components/loading.vue';
import projectCard from '@/components/projectCard.vue';
import projectAdd from '@/components/addProject.vue';

export default {
  components: {
    projectCard,Loader,projectAdd,},data() {
    return {
      userid: this.$route.params.userId,//02 Put array data here
      projects: [],loading: true,createNew: false,};
  },created() {
    //01 Get datas in realtime then pass an array data to projects: []
    const db = firebase.firestore()
    .collection('user')
    .doc(this.userid) //$route.params.userId
    .collection('projects')
    .orderBy('createdAt','desc');
    db
      .onsnapshot((querysnapshot) => {
        querysnapshot.forEach((doc) => {
            this.projects.push(doc.data());
        });
        if (this.projects.length >= 0) {
          this.loading = false;
        } else if (this.projects.length <= 0) {
          this.loading = false;
        }
      });
  },methods: {
    newProject() {
      if (this.createNew !== true) {
        this.createNew = true;
      } else {
        this.createNew = false;
      }
    },};
</script>


projectCard.vue:将每个数据插入数组

<template>
  <div class="projectCard">
    <div class="user-list">
      <div class="columns">
        <div class="column is-8">
          <h3>{{ project.projectname }}</h3>
          <p>{{ project.slug }}</p>
          <p>Why : {{ project.why }}</p>
          <p>{{ project.phase }}</p>
        </div>
        <div class="column is-4 right">
          <router-link class="button is-primary" :to="{ name: 'viewproject',params: { projectId: project.slug }}">
            Find out more!
          </router-link>
          <button @click="deleteProject"> Delete </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import firebase from '@/firebase/firestore';

export default {
  name: 'ProjectCard',props: {
    // Holds array data from parent-component; projectList.vue
    project: Object,methods: {
    // Delete a task
    deleteProject() {
    firebase.firestore().collection('user').doc(this.project.userId)
    .collection('projects')
    .where('slug','==',this.project.slug)
    .get()
    .then((snapshot) => {
      snapshot.forEach((doc => {
      console.log(doc.data().slug);
      doc.ref.delete();
      alert('You have deleted the project!' + doc.data().slug);
      })) 
    })
    },};

</script>



addProject.js:添加任务(可从projectList.vue中呈现的另一个组件访问此功能)

import firebase from '@/firebase/firestore';

export default {
  addProject(createdAt,userId,projectname,why,phase){
    const db = firebase.firestore().collection("user")
    .doc(userId).collection("projects"); // "Project"という名前のコレクションへの参照を作成
    db.add({
      createdAt: createdAt,userId: userId,projectname: projectname,why: why,phase: phase,slug: this.generateUUID(),})
      .then(function (docRef) {
        console.log('Document written with ID: ',docRef.id);
        alert('Well done! You have created a new project!');
      })
      .catch(function (error) {
        console.error('Error adding document: ',error);
      });
  },generateUUID() {
    let d = new Date().getTime();
    let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,function (c) {
      let r = (d + Math.random() * 16) % 16 | 0;
      d = Math.floor(d / 16);
      return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
    });
    return uuid;
  },};

感谢您花费宝贵的时间阅读本文,并帮助我解决此问题! 期待听到你们的一些想法!

zhan923518648 回答:在列表中添加/删除项目后,请使用onSnapshot正确渲染任务列表 无法正常工作

这是因为每次触发侦听器时,您都会收到查询的整个结果,即与之对应的所有文档。

您基本上有两个选择:

选项1:重新初始化数组

在填充数组之前重新初始化数组,如下所示:

  created() {

    const db = firebase.firestore()
    .collection('user')
    .doc(this.userid) //$route.params.userId
    .collection('projects')
    .orderBy('createdAt','desc');

    this.projects = [];  <-- See here

    db
      .onSnapshot((querySnapshot) => {
        querySnapshot.forEach((doc) => {
            this.projects.push(doc.data());
        });
        if (this.projects.length >= 0) {
          this.loading = false;
        } else if (this.projects.length <= 0) {
          this.loading = false;
        }
      });
  },

选项2:听实际更改

doc中所述,您可以检测到“ 实际更改以查询快照之间的查询结果”。

例如,您只能处理添加项,如下所示:

db
  .onSnapshot((querySnapshot) => {
    querySnapshot.docChanges().forEach((change) => {
        if (change.type === "added") {
            this.projects.push(change.doc.data());
        }
        //....
    });
    //....
  });
本文链接:https://www.f2er.com/3128678.html

大家都在问