I don't have access to your specific Firestore data and mocking it would be quite difficult so I used JSONplaceholder for my example.
Here is how I would handle such case
index.vue
<template>
<div>
<post-card v-for="user in users" :key="user.id" :user="user" />
</div>
</template>
<script>
export default {
components: {
'post-card': () => import('~/components/PostCard.vue'),
},
data() {
return {
users: [],
}
},
async mounted() {
this.users = await this.$axios.$get(
'https://jsonplaceholder.typicode.com/users/'
)
},
// methods: {
// async fetchUsername(id) {
// const snapshot = await this.$fire.firestore
// .collection('users')
// .doc(id)
// .get()
// console.log('id', snapshot.data())
// return snapshot.data().name
// },
// },
}
</script>
PostCard.vue
<template>
<div>
<span>{{ user.name }}</span>
<pre>{{ details }}</pre>
<hr />
</div>
</template>
<script>
export default {
name: 'PostCard',
props: {
user: {
type: Object,
default: () => {},
},
},
data() {
return {
details: {},
}
},
async mounted() {
this.details = await this.$axios.$get(
`https://jsonplaceholder.typicode.com/users/${this.user.id}`
)
},
}
</script>
Here, I'm using this.$axios.$get
but it's basically a fancy axios + .data
combo, nothing special.
I didn't used :userName="userName(post.userId)"
in the parent as you because this is not feasible per se. A template is synchronous in that case, meaning that you will not get post.userId
when running your function because the request would still be pending. Meanwhile, your child needs this info straight to render himself.
In Vue, you usually do this kind of logic inside of the child component itself or in a mounted
hook in pair with the collection fetch. This is mainly because of how a Vue child component mounts as explained here: https://stackoverflow.com/a/44319825/8816585
You could maybe use this kind of mounted trick but I don't recommend working in that way because it will be hacky, overall more difficult and unnecessary.