【问题标题】:Is it possible to render real-time changes in Firebase data within a Vue app?是否可以在 Vue 应用程序中呈现 Firebase 数据的实时变化?
【发布时间】:2019-08-24 10:38:55
【问题描述】:

我在 Vue 应用程序中使用 Firebase 进行身份验证和数据库。我正在开发的组件会监听特定用户的“朋友”集合中的变化。

我只想在实时反映数据库更改的同时显示朋友列表。

到目前为止,我采取了两种方法,都导致成功捕获更改的相同问题,但无法在 dom 中显示更改。

方法一

在 created() 函数中,我使用 .onSnapshot() 函数添加我的侦听器。这成功地捕获了数据库中的更改。但是,如果我将 this.friends 设置为更新后的值,屏幕不会改变。

方法2

使用 Vuex 加载好友列表。我为商店创建了一个监视功能,可以成功跟踪更改。但是在这个手表功能中更改this.friends也不会更新屏幕。

对简单变量的反应按预期工作。

<template>
  <v-container fluid>
    {{ friends }}
  </v-container>
</template>

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

export default {
  name: 'Test',
  data() {
    return {
      friends: []
    }
  },
  created() {
    let firebaseUser = firebase.auth().currentUser
    let ref = db.collection('users')
    ref.where('user_id', '==', firebaseUser.uid).limit(1).get()
    .then( snapshot => {
      if (snapshot.docs[0].data()) {
        db.collection("users").doc(snapshot.docs[0].id)
        .onSnapshot(function(doc) {
          let user = doc.data()
          console.log('friends', user.friends) // outputs correctly
          this.friends = user.friends // does not update dom
        })
      }
    })
  },
}
</script>

【问题讨论】:

    标签: javascript firebase vue.js google-cloud-firestore


    【解决方案1】:

    您可以按如下方式设置监听器:

    <template>
       <v-container fluid>
          {{ friend }}
       </v-container>
    </template>
    
    <script>
    import db from '@/firebase/firestore'
    import firebase from 'firebase'
    
    export default {
      name: "Test",
      data() {
        return {
          friend: null
        };
      },
      created() {
        const firebaseUser = firebase.auth().currentUser
        const ref = db.collection('users')
    
        ref
          .where('user_id', '==', firebaseUser.uid)
          .limit(1)
          .onSnapshot(querySnapshot => {
             let f = querySnapshot.docs[0].data();
             f.id = querySnapshot.docs[0].id;
             this.friend = f;
          });
      }
    };
    </script>
    
    <style>
    </style>
    

    仅供参考,如果要删除.limit(1) 并显示所有friends,请执行以下操作:

    <template>
      <v-container fluid>
        <template v-for="f in friends">
          <div>{{ f.id }}</div>
        </template>
      </v-container>
    </template>
    
    <script>
    import db from '@/firebase/firestore'
    import firebase from 'firebase'
    
    export default {
      name: "Test",
      data() {
        return {
          friends: []
        };
      },
      created() {
        const firebaseUser = firebase.auth().currentUser
        const ref = db.collection('users')
    
        ref
          .where('user_id', '==', firebaseUser.uid)
          .onSnapshot(querySnapshot => {
            var fArray = [];
            querySnapshot.forEach(doc => {
              let f = doc.data();
              f.id = doc.id;
              fArray.push(f);
            });
            this.friends = fArray;
          });
      }
    };
    </script>
    
    <style>
    </style>
    

    【讨论】:

    • 感谢@renaud-tarnec,您的解决方案已经奏效。似乎我的方法有第二个嵌套异步调用,它影响了反应性。通过简化调用,它按预期更新。非常感谢!
    【解决方案2】:

    如果你使用 Vuex,你是否使用 Vuex,那么首先你必须在 Computed Property 中导入 getter,否则如果你不使用 Vuex,你必须观察正在变化的数据。 您必须观看 Computed Property Remember 组件将仅重新渲染数据属性更改,如果数据更改然后 vue 知道该组件中的某些更改,它将重新渲染该组件 您必须按照以下答案为您提供解决方案 Watching Computed Property in Vue

    【讨论】:

    • 感谢您的意见。我确实尝试过以这种方式使用 Vuex,它在输出到控制台时有效,但没有触发重新渲染。基于 renaud-tarnec 代码,似乎像我一样嵌套 firebase 调用会导致反应性问题。感谢您的意见!
    猜你喜欢
    • 2012-01-11
    • 1970-01-01
    • 1970-01-01
    • 2018-03-01
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多