javascript - Vue子组件在第一页加载时不显示动态数据
问题描述
鉴于下面的代码,我的子组件警报在父挂载函数中的任何代码之前触发。
结果,看起来孩子在数据准备好之前已经完成了初始化,因此在重新加载之前不会显示数据。
数据本身可以从 API 中很好地返回,因为原始 JSON 显示在v-card
布局中。
我的问题是如何确保在子组件加载之前,Parent 中请求的数据已准备好?我发现的所有内容都集中在使用 props 传入的静态数据上,但是当必须首先获取数据时,这似乎完全失败了。
在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 组件声明为类)
constructor()
因此,您应该将代码移动到生命周期挂钩而不是使用created()
在这种情况下,这应该足以修复您的代码,但只是因为组件的使用在 Parent 中Notes
受到保护- 只有在不是空数组后才会创建组件v-if="notes.length"
notes
这在很多情况下是不够的!
created()
生命周期钩子(和data()
函数/钩子)只对每个组件执行一次。里面的代码是一次性初始化的。因此,当/如果父组件更改notesArr
prop 的内容时(有时在将来),eventChanges
则不会更新。即使您知道 parent 永远不会更新 prop,请注意,出于性能原因,Vue 倾向于在使用 / 渲染列表或在相同类型的组件之间切换时尽可能重用现有组件实例-而v-for
不是破坏现有组件并创建新组件, Vue 只是更新道具。应用程序突然看起来无缘无故坏了......v-if
v-else
这是许多没有经验的用户会犯的错误。您可以在这里找到很多关于 SO 的问题,例如“我的组件不是反应式”或“如何强制我的组件重新渲染”,其中有很多答案建议使用:key
hack 或使用 watcher ....有时有效,但几乎总是更多复杂然后正确的解决方案
正确的解决方案是将您的组件(如果可以 - 有时不可能)编写为纯组件(文章适用于 React,但原则仍然适用)。在 Vue 中实现这一点的非常重要的工具是计算属性
因此,不要引入eventChanges
data 属性(它可能是反应性的,也可能不是反应性的 - 这在您的代码中不清楚),您应该将其设为notesArr
直接使用 prop 的计算属性:
get eventChanges() {
return this.notesArr.map(note => {
return {
eventInfo: {
name: note.name,
group: note.groupNo || null,
date: note.displayDate,
},
note: note.noteToPresenter
}
})
}
现在,每当notesArr
父级更改 prop 时,eventChanges
都会更新并且组件将重新渲染
笔记:
- 你过度使用
async
. 您的getNotes
函数不执行任何异步代码,因此只需将其删除。 - 也不要混合
async
-then
它令人困惑
任何一个:
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
})
推荐阅读
- javascript - 我的 addEventListner 在 javascript 中返回 null 的问题
- python - 在特定时间运行 python 代码而不使用 cron 作业
- python - 互联网校验和——将十六进制数字加在一起以获得校验和
- python - 我想加入 2 个表,但在 2 个不典型的东西上,比如 slug 和 path 、 slug abc 和 path /article
- html - 如何使用 FireFox 在 html 中显示 xml?
- jquery - 将焦点放在使用 jQuery 隐藏的输入类型上
- svg - 我正在尝试使用颤振 svg,但使用黑色 svg 加载
- c# - 如何在 InitializeComponent() 中阻止一个事件总是先于另一个事件发生?-winform C#
- python - 查找数组中总和为给定值的所有元素对
- http - 在反向代理后面呈现绝对 URL 的正确方法是什么?