Vue子组件在第一个页面加载时不显示动态数据



对于下面的代码,我的子组件警报在父组件挂载函数中的任何代码之前触发。

结果,在数据准备好之前,子进程似乎已经完成了初始化,因此在重新加载数据之前不会显示数据。

数据本身很好地从API返回,因为原始JSON显示在布局中的v-card中。

我的问题是如何确保父组件中请求的数据在子组件加载之前准备好?我发现的任何东西都集中在使用props传递的静态数据上,但是当必须首先获取数据时,似乎这完全失败了。

在Parent的mounted()中,我有这个代码,它是检索数据的。

const promisesArray = [this.loadPrivate(),this.loadPublic()]
await Promise.all(promisesArray).then(() => {
console.log('DATA ...') // fires after the log in Notes component
this.checkAttendanceForPreviousTwoWeeks().then(()=>{
this.getCurrentParticipants().then((results) => {     
this.currentP = results
this.notesArr = this.notes // see getter below   
})

在父

中检索数据的getter
get notes() {
const newNotes = eventsModule.getNotes
return newNotes
}

父模板中的组件:

<v-card light elevation="">
{{ notes }} // Raw JSON displays correctly here
// Passing the dynamic data to the component via prop
<Notes v-if="notes.length" :notesArr="notes"/>
</v-card>

子组件:

...
// Pickingn up prop passed to child
@Prop({ type: Array, required: true })
notesArr!: object[]
constructor()
{
super();    
alert(`Notes : ${this.notesArr}`) // nothing here 
this.getNotes(this.notesArr)    
}
async getNotes(eventNotes){
// THIS ALERT FIRES BEFORE PROMISES IN PARENT ARE COMPLETED
alert(`Notes.getNotes CALL.. ${eventNotes}`) // eventNotes = undefined
this.eventChanges = await eventNotes.map(note => {
return {
eventInfo: {
name: note.name,
group: note.groupNo || null,
date: note.displayDate,
},     
note: note.noteToPresenter
}
})
}
...

我对Vue比较陌生,所以如果我忽略了一些基本的东西,请原谅我。我一直在试图解决它的几天,现在不能弄清楚,所以任何帮助是非常感激!

如果您是Vue的新手,我建议您阅读它的完整文档和您正在使用的工具- Vue -class-component(这是Vue插件添加的API,用于将Vue组件声明为类)

  1. 类组件的注意事项-始终使用生命周期钩子而不是constructor

所以你应该把代码移到created()生命周期钩子

而不是使用constructor()

在这种情况下,这应该足以修复你的代码,但仅仅是因为Notes组件的使用是由父组件中的v-if="notes.length"保护的-该组件只有在notes不是空的情况下才会被创建

在很多情况下这是不够的!

  1. created()生命周期钩子(和data()函数/钩子)对每个组件只执行一次。里面的代码是一次性初始化. 因此,当/如果父组件更改notesArrprop的内容时(有时在将来),eventChanges将不会得到更新。即使您知道父组件永远不会更新道具,请注意,出于性能原因,当使用v-for呈现列表或使用v-if/v-else在相同类型的组件之间切换时,Vue倾向于在可能的情况下重用现有组件实例-而不是销毁现有组件并创建新组件,Vue只是更新道具。应用程序突然无缘无故地看起来坏了…

这是许多没有经验的用户会犯的错误。你可以在SO上找到很多问题,比如"我的组件没有反应性"。或者"如何强制组件重新渲染";许多答案建议使用:key黑客或使用观察者....这有时有效,但几乎总是比正确的解决方案复杂得多

正确的解决方案是把你的组件写成纯组件(如果可以的话——有时是不可能的)(这篇文章是针对React的,但原则仍然适用)。在Vue中实现这一点的一个非常重要的工具是计算属性

所以,不是引入eventChanges的数据属性(它可能是响应的,也可能不是响应的——这在你的代码中不是很清楚),你应该让它成为直接使用notesArrprop的计算属性:

get eventChanges() {
return this.notesArr.map(note => {
return {
eventInfo: {
name: note.name,
group: note.groupNo || null,
date: note.displayDate,
},     
note: note.noteToPresenter
}
})
}

现在只要notesArr道具被父道具改变,eventChanges就会被更新,组件将重新渲染

指出:

  • 您过度使用async。您的getNotes函数不执行任何异步代码,所以只需删除它。
  • 也不要把asyncthen混在一起——这会混淆

:

const promisesArray = [this.loadPrivate(),this.loadPublic()]
await Promise.all(promisesArray)
await this.checkAttendanceForPreviousTwoWeeks()
const results = await this.getCurrentParticipants()
this.currentP = results
this.notesArr = this.notes

或:

const promisesArray = [this.loadPrivate(),this.loadPublic()]
Promise.all(promisesArray)
.then(() => this.checkAttendanceForPreviousTwoWeeks())
.then(() => this.getCurrentParticipants())
.then((results) => {     
this.currentP = results
this.notesArr = this.notes
})

优秀的学习资源

最新更新