Vue 无法读取对象属性的未定义属性,但仅限于模板中
我在 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")
},
它在已安装状态下运行
在模板中访问数据之前,务必确保数据可用。这些类型的错误 (无法读取未定义的属性...) 大多是由于缺乏先检查而发生的。
对于您而言,在访问
plans 数组
或
plans 的键 (plans[0])
之前,请创建一个计算属性或直接在模板上应用条件来检查它是否在 DOM 中可用,如下所示-
- 如果您想循环遍历所有计划项目-
<template>
<div v-if="plans && plans.length">
<template v-for="(item, index) in plans">
<h1>{{ item.name }}</h1>
</template>
</div>
</template>
- 如果您只想显示单个项目-
<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>
data() {
return {
plans: Object,
}
我不确定是否有利用方法和安装的解决方案,但我通过使用 setup() 而不是方法和安装解决了这个问题。我将引用的值设置为完整的对象数组,然后在设置结束时返回该值,并且所有内容都可以在模板中正确访问。