当我处理 vue3 refs 数组时有问题

have problem when i handle vue3 refs array

我在处理 vue3 引用时遇到问题。

我从 firestore 获取数据。

我记录了 [documents],它工作正常。

但是当我从文档的第一个数组中获取值时

例如,

我想要的值:abc1 (first array's displayName)

所以我试过了

console log

0. documents (works, results below)


1. documents.value.displayName (error)

2. documents.value[0].displayName (error)
Uncaught (in promise) TypeError: Cannot read property '0' of null
    at setup (Write.vue?125b:56)

但失败了。

如何从 refs 数组中获取值?

Log document

RefImpl {_shallow: false, __v_isRef: true, _rawValue: null, _value: null}
__v_isRef: true
_rawValue: Array(2)
0: {displayName: "abc1", orgName: "amazon", email: "aaa@aaa.com", regDate2: "2021-7-27", …}
1: {displayName: "abc2", email: "aaa@aaa.com", orgName: "google", …}

设置功能

    setup() {
      const title = ref('')
      const contents = ref('')
      const { user } = getUser()
      const userUid = user.value.uid
      const { documents } = getCollection('user')
      console.log(documents, 'documents log')
      console.log(documents.value[0].displayName, 'documents value log')
      return {title, contents, user, documents }
    }

getCollection.js

const getCollection = (collection, query) => {

  const documents = ref(null)
  const error = ref(null)

  // register the firestore collection reference
  let collectionRef = projectFirestore.collection(collection)

  if (query) {
    collectionRef = collectionRef.where(...query)
  }

  const unsub = collectionRef.onSnapshot(snap => {
    let results = []
    snap.docs.forEach(doc => {
      results.push({...doc.data()})
    });
    
    // update values
    documents.value = results
    error.value = null
  }, err => {
    console.log(err.message)
    documents.value = null
    error.value = 'could not fetch the data'
  })

  watchEffect((onInvalidate) => {
    onInvalidate(() => unsub());
  });

  return { error, documents }
}

export default getCollection

getCollection 异步更新 documents 在您 将其记录到控制台后。请注意,console.log 记录对象的 实时引用 ,因此您将在浏览器控制台中看到最新的值,而不是您记录时的实际值。如果你想看到实际值,JSON.stringify它:

export default {
  setup() {
    //...                
    console.log(JSON.stringify(documents.value), 'documents log')
  }
}

上面显示的日志可能会记录 null,因为 ref 尚未更新。

解决方案

要在 documents 中记录第一个元素的 displayName,请在 documents ref 上使用 watch,当 documents.value 是更新:

import { watch } from 'vue'
 
export default {
  setup() {
    const { documents } = getCollection('user')

    watch(documents,
          newValue => {
            console.log(newValue?.[0].displayName)
          },

          // use `deep` flag to observe property changes to array elements
          { deep: true }
    )
  }
}

demo