当我从一页到另一页时,我试图显示一个活动指示器。目标页面中包含许多组件,加载需要时间。这就是为什么当加载了所有子组件时,我需要某种方式来侦听,这时告诉变量isBussy为false
<template>
<StackLayout>
<ActivityIndicator :busy="isBussy" v-if="isBussy" />
<StackLayout v-else>
<Component1 />
<Component2 />
<Component3 />
<Component4 />
</StackLayout>
<StackLayout>
</template>
<script>
import Component1 from '~/components/Component1'
import Component2 from '~/components/Component2'
import Component3 from '~/components/Component3'
import Component4 from '~/components/Component4'
export default {
data() {
return {
isBussy: true
}
},
mounted() {
this.$nextTick(function() {
// Code that will run only after the
// entire view has been re-rendered
this.isBussy = false
})
}
}
</script>此代码不起作用,因为一旦导航从上一页显示为:@tap="$goto('otherPage', { props: { foo: bar } })"
它仍然停留在初始页面上,所有组件都开始在目标页面的背景中加载,但没有显示父页,只有在整个过程结束时才更改为父页,并且永远不要按预期显示/隐藏活动指示符。
顺便说一句,当我请求并用承诺处理这些行为时,这种预期的行为会完美地工作,然后打开或关闭状态中的变量,它就能工作了。但是,我不能在页面之间的导航中复制这种行为,并且要侦听加载所有组件。
编辑
最后,我在网上找到了一个小窍门,达到了我想要的行为。
mounted() {
setTimeout(() => {
this.isBussy = false
}, 500)
},这导致所有子组件的呈现只延迟了一点点,从而显示了活动指示符,但不足以产生未检测到其他块中包含的任何组件并开始呈现的结果。
发布于 2019-04-08 04:38:03
我认为这里有两个主要的想法需要理解。我会描述这两件事。
1.在不阻塞呈现的情况下获取数据的一般技术
听起来您似乎在父组件级别上理解了这个概念,但接下来您会问如何对此页面包含的子组件执行非常类似的操作。
在我的组件中,我处理这个问题的方式是,我的数据默认为isLoading状态。然后,在beforeMount()或mounted()中,我执行异步操作并对页面的数据进行必要的更改。
当我们查看子组件时,问题就完全是递归的了。您希望确保您的子组件正在呈现,并且任何需要在其实现中进行的长时间运行的数据取取都只会导致它们在完成抓取之后重新呈现。
下面是一个有用的示例:https://codesandbox.io/embed/r4o56o3olp --这个示例使用Nuxt。除了加法fetch()和asyncData()方法之外,这里Vue生命周期钩子的其余部分都是相同的。
我使用new Promise和setTimeout来演示一个使用承诺和异步操作的操作。(例如axios.get(..))
About页面加载,beforeMount()生命周期钩子以不阻止页面呈现的方式执行异步抓取。
我使用beforeMount()钩子,因为根据这里( https://alligator.io/vuejs/component-lifecycle/ ),一旦页面的数据是反应性的,它是我们可以访问的第一个生命周期钩子。(因此,如果在模板中使用this.myDataProp,则修改{{ myDataProp }}将触发重呈现)。
我还包括一个子组件,我故意让它的数据需要两倍的时间来加载。由于我再次允许组件立即呈现,然后在适当的生命周期钩子中处理数据的获取/更新,所以我可以在最终用户感知要加载的页面时进行管理。
在我的工作示例中,LongLoadingComponent完成了与About页面相同的技术。
一旦您了解了如何使用beforeMount()或mounted()获取数据,然后更新状态,我认为诀窍是花点时间认真考虑组件的默认状态。当第一次呈现时,在完成任何数据获取/长时间运行操作之前,用户应该看到什么?
一旦确定了默认(尚未加载)组件的外观,请尝试将其呈现到屏幕上,然后再添加获取和更新状态数据的逻辑。
2.侦听子组件何时完成父组件的呈现
这利用了上述技术,但包括使用updated()钩子和发出自定义事件( https://v2.vuejs.org/v2/guide/components-custom-events.html )。
如果您确实希望侦听您的子组件何时完成呈现,则可以在$emit钩子中设置一个自定义事件。也许是这样的(在您的一个子组件中)
if (this.dataLoaded) { this.$emit('loadedAndRendered') }因此,当子异步操作完成时,它可以将它的dataLoaded属性翻转为true。如果dataLoaded在子<template>中的某个位置使用,那么组件应该重新呈现(因为它是“已完成的”状态)。当子对象重新呈现时,updated()钩子应该触发.(请参见:https://alligator.io/vuejs/component-lifecycle/ ),我包含了if (this.dataLoaded)部分,只是为了处理在中间数据更新期间可能调用updated()钩子的情况。(我们只希望在子程序加载/更新完成时发出loadedAndRendered事件。)
3.关于通用nuxt应用程序的其他注意事项
直到我写了这个答案之后,我才意识到你没有使用Nuxt。不过,我要添加这个,以防其他Nuxt用户碰巧遇到这种情况。
我增加这个部分仅仅是因为我花了一些专注的时间才能把我的头绕过去。Nuxt通用应用程序同时执行服务器端和客户端的呈现.首先,理解客户端上呈现的东西与在服务器上呈现的东西是有点困难的。在我上面链接的工作示例中,当您访问about页面时,还可以看到该组件是从服务器获取的,还是只是由客户端呈现的。
我建议使用Page的fetch()和asyncData()方法,看看某些东西在屏幕上呈现时会产生什么影响。( https://nuxtjs.org/api/pages-fetch/ ) ( https://nuxtjs.org/api/ )。看看这些方法有什么用,也可以帮助我识别它们对什么没有用处。
如果您正在使用Vuex存储,我建议您查看刷新页面或使用a而不是a在页面之间导航时会发生什么。(在这里看到类似于SSR模式图的内容会很有帮助:https://nuxtjs.org/guide#schema )
..I还没有完全理解Webpack为Universal应用程序提供的捆绑和交付行为的细节(见图的右侧:https://medium.freecodecamp.org/universal-application-code-structure-in-nuxt-js-4cd014cc0baa )。
https://stackoverflow.com/questions/55564807
复制相似问题