开发者问题收集

Vue 无法读取对象属性的未定义属性,但仅限于模板中

2022-12-14
1336

我在 vue 中创建了一个变量,其值为

data() {
        return {
            plans: [],
}

稍后会向​​ Plans 提供推送的对象。当我在 js 中打印该对象时,它会给出 {id: 'filler', name: 'Premium', priceId: 'filler', price: '10000'> 。我还可以使用 console.log(this.plans[1]['name']) 专门获取名称,它会正确给出“Premium”。但是,在模板中,我尝试使用 <h1>{{plans[0].name}}</h1> 显示名称(我也尝试使用 ['name']),它显示 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'name')。但是,如果我只给它 <h1>{{plans[0]}}</h1> ,它就会正确显示整个对象。我非常困惑我遗漏了什么,如果需要更多信息,请告诉我。

编辑:数组填充了以下内容

async getPlans(){
        
        const db = getFirestore()
        const productsRef = collection(db, "products")
        const productsQuery = query(productsRef, where("active","==", true))
        const productsQuerySnap = await getDocs(productsQuery)
        // console.log(productsQuerySnap[0])
        // const temp = []
        for (let i = 0; i<2; i++){
            // const doc = i.docs
            console.log(productsQuerySnap.docs[i])
            const pricesRef = collection(db, "products", productsQuerySnap.docs[i].id, "prices")
            const pricesQuerySnap = await getDocs(pricesRef)
            const name = productsQuerySnap.docs[i]["_document"]["data"]["value"]["mapValue"]["fields"]["name"]["stringValue"]
            console.log(pricesQuerySnap.docs[0]["id"])
            const priceId = pricesQuerySnap.docs[0]["id"]
            const price = pricesQuerySnap.docs[0]["_document"]["data"]["value"]["mapValue"]["fields"]["unit_amount"]['integerValue']
            console.log({id: productsQuerySnap.docs[i].id, name: name, priceId: priceId, price: price})
            this.plans.push({id: productsQuerySnap.docs[i].id, name: name, priceId: priceId, price: price})
        }
        console.log(this.plans[0]['name'], "plans is running")
    

  },

它在已安装状态下运行

3个回答

在模板中访问数据之前,务必确保数据可用。这些类型的错误 (无法读取未定义的属性...) 大多是由于缺乏先检查而发生的。

对于您而言,在访问 plans 数组plans 的键 (plans[0]) 之前,请创建一个计算属性或直接在模板上应用条件来检查它是否在 DOM 中可用,如下所示-

  1. 如果您想循环遍历所有计划项目-
<template>
  <div v-if="plans && plans.length">
     <template v-for="(item, index) in plans">
       <h1>{{ item.name }}</h1>
     </template>
  </div>
</template>
  1. 如果您只想显示单个项目-
<template>
  <div v-if="plans && plans.length && plans[0]">
    <h1>{{ plans[0].name }}</h1>
  </div>
</template>

推荐-

不要写 plans && 在模板中直接使用 .plans.length ,您可以为其创建一个计算属性,并在任何地方访问而无需重复代码-

<template>
  <div v-if="isPlansAvailable">
     <template v-for="(item, index) in plans">
       <h1>{{ item.name }}</h1>
     </template>
  </div>
</template>

<script>
  export default {
    name: "ComponentName",
    
    data() {
      return {
        plans: [],
      }
    },
  
    computed: {
      isPlansAvailable() {
        return this.plans && this.plans.length;
      }
    },
    
    mounted() {
      // YOUR API METHOD
    },
  }
</script>
Neha Soni
2022-12-14
data() {
        return {
            plans: Object,
}
HanKBeatz
2022-12-14

我不确定是否有利用方法和安装的解决方案,但我通过使用 setup() 而不是方法和安装解决了这个问题。我将引用的值设置为完整的对象数组,然后在设置结束时返回该值,并且所有内容都可以在模板中正确访问。

daredevil
2022-12-14