在 vue.js 中渲染子组件之前,请等待父组件安装/准备就绪
Wait until parent component is mounted / ready before rendering child in vue.js
在我的 SPA 应用程序中,我有一个 <app-view>
包装器来处理基本应用程序代码(加载用户数据、呈现导航栏和页脚等),并有一个 slot
用于呈现实际页面。此 插槽仅在用户数据可用时呈现 。
创建此包装器是因为某些页面需要不同的基本代码,因此我不能再将此基本代码保留在包含 <router-view>
的主应用程序中。
我尝试查看 vue-router 是否提供高级选项或建议用于切换基本代码的设计模式,但没有找到任何东西。
问题是 子组件将在父组件挂载之前渲染,即在父组件决定不渲染子组件之前(因为它正在加载用户数据) .这会导致 undefined as no attribute foo
.
之类的错误
正因为如此,我正在寻找一种方法来推迟子渲染,直到它的父渲染被挂载。
尝试了几个选项后,看来我需要硬着头皮明确定义我的组件所依赖的数据,如下所示:
<app-view>
<div v-if='currentProfile'>
...
</div>
</div>
(currentProfile
从 vuex store getter 接收,并在 app-view
内获取)
您实际上可以将 v-if
放在组件中的 <slot>
标记上。
new Vue({
el: '#app',
render: function(createElement) {
return createElement(
// Your application spec here
{
template: `<slotty :show="showSlot"><span> here</span></slotty>`,
data() {
return {
showSlot: false
}
},
components: {
slotty: {
template: `<div>Hiding slot<slot v-if="show"></slot>.</div>`,
props: ['show']
}
},
mounted() {
setTimeout(() => this.showSlot = true, 1500);
}
}
);
}
})
<script src="//unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
</div>
我遇到了类似的问题,但不是 SPA。我有 child 个组件需要来自 parent 的数据。问题是数据只会在 parent 完成安装后生成,所以我最终在 children.
中得到了空值
我就是这样解决的。我使用 v-if
指令仅在 parent 完成挂载后挂载 children。 (在mounted()
方法中)见下面的例子
<template>
<child-component v-if="isMounted"></child-component>
</template>
<script>
data() {
isMounted: false
}, mounted() {
this.isMounted = true
}
</script>
之后,child可以从parent获取数据。
它有点无关,但我希望它能给你一个想法。
对于任何想在父组件从 API 调用中获取数据后立即显示子组件的人,您应该使用如下内容:
<template>
<child-component v-if="itemsLoaded"></child-component>
</template>
<script>
data() {
itemsLoaded: false
},
methods: {
getData() {
this.$axios
.get('/path/to/endpoint')
.then((data) => {
// do whatever you need to do with received data
// change the bool value here
this.itemsLoaded = true
})
.catch((err) => {
console.log(err)
})
},
},
mounted() {
this.getData()
// DONT change the bool value here; papa no kiss
this.itemsLoaded = true
}
</script>
如果您尝试在 mounted()
方法中更改布尔值 this.itemsLoaded = true
,在调用 getData()
方法后,您将得到不一致的结果,因为您可能会或可能不会收到this.itemsLoaded = true
执行前的数据。
在我的 SPA 应用程序中,我有一个 <app-view>
包装器来处理基本应用程序代码(加载用户数据、呈现导航栏和页脚等),并有一个 slot
用于呈现实际页面。此 插槽仅在用户数据可用时呈现 。
创建此包装器是因为某些页面需要不同的基本代码,因此我不能再将此基本代码保留在包含 <router-view>
的主应用程序中。
我尝试查看 vue-router 是否提供高级选项或建议用于切换基本代码的设计模式,但没有找到任何东西。
问题是 子组件将在父组件挂载之前渲染,即在父组件决定不渲染子组件之前(因为它正在加载用户数据) .这会导致 undefined as no attribute foo
.
正因为如此,我正在寻找一种方法来推迟子渲染,直到它的父渲染被挂载。
尝试了几个选项后,看来我需要硬着头皮明确定义我的组件所依赖的数据,如下所示:
<app-view>
<div v-if='currentProfile'>
...
</div>
</div>
(currentProfile
从 vuex store getter 接收,并在 app-view
内获取)
您实际上可以将 v-if
放在组件中的 <slot>
标记上。
new Vue({
el: '#app',
render: function(createElement) {
return createElement(
// Your application spec here
{
template: `<slotty :show="showSlot"><span> here</span></slotty>`,
data() {
return {
showSlot: false
}
},
components: {
slotty: {
template: `<div>Hiding slot<slot v-if="show"></slot>.</div>`,
props: ['show']
}
},
mounted() {
setTimeout(() => this.showSlot = true, 1500);
}
}
);
}
})
<script src="//unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
</div>
我遇到了类似的问题,但不是 SPA。我有 child 个组件需要来自 parent 的数据。问题是数据只会在 parent 完成安装后生成,所以我最终在 children.
中得到了空值我就是这样解决的。我使用 v-if
指令仅在 parent 完成挂载后挂载 children。 (在mounted()
方法中)见下面的例子
<template>
<child-component v-if="isMounted"></child-component>
</template>
<script>
data() {
isMounted: false
}, mounted() {
this.isMounted = true
}
</script>
之后,child可以从parent获取数据。 它有点无关,但我希望它能给你一个想法。
对于任何想在父组件从 API 调用中获取数据后立即显示子组件的人,您应该使用如下内容:
<template>
<child-component v-if="itemsLoaded"></child-component>
</template>
<script>
data() {
itemsLoaded: false
},
methods: {
getData() {
this.$axios
.get('/path/to/endpoint')
.then((data) => {
// do whatever you need to do with received data
// change the bool value here
this.itemsLoaded = true
})
.catch((err) => {
console.log(err)
})
},
},
mounted() {
this.getData()
// DONT change the bool value here; papa no kiss
this.itemsLoaded = true
}
</script>
如果您尝试在 mounted()
方法中更改布尔值 this.itemsLoaded = true
,在调用 getData()
方法后,您将得到不一致的结果,因为您可能会或可能不会收到this.itemsLoaded = true
执行前的数据。