在beforeRouteEnter内访问应用程序

sch*_*max 5 vue.js vue-router

当组件准备由 vue 路由器呈现时,我想在应用程序根目录中显示一些加载动画。

已经找到这个问题,建议使用导航守卫,还有一个问题,其中接受的答案显示了如何使用beforeEach守卫在 中设置变量app,显示加载动画。

问题是这在深度链接到某个路由时不起作用(初始 url 包括路由路径,例如“someurl#/foo”)。在beforeEach后卫根本不会被调用即可。

所以我切换到加载组件的beforeRouteEnter保护,这也允许我只显示某些组件的加载动画:

应用程序:

var app = new Vue({
  el: '#app',
  data: { loading: false }
  router: router
});
Run Code Online (Sandbox Code Playgroud)

成分:

var Foo = { 
  template: '<div>bar</div>',
  beforeRouteEnter: function(to, from, next) {
    app.loading = true; // 'app' unavailable when deep-linking
    // do some loading here before calling next()...
    next();
  }
}
Run Code Online (Sandbox Code Playgroud)

但是后来我发现当深度链接到组件时,app在 中不可用beforeRouteEnter,因为它在初始化过程中很早就被调用了。

我不想在应用程序数据声明中设置loadingtrue,因为我可能会在某个时候决定深度链接到另一个路由,其组件不需要加载动画。

小智 5

我相信,您的解决方案是正确的。但是,我建议改用 next() 函数。正如 vue-router 文档中所写。 https://router.vuejs.org/en/advanced/navigation-guards.html

beforeRouteEnter 守卫无法访问它,因为在确认导航之前调用了守卫,因此甚至还没有创建新的输入组件。

但是,您可以通过将回调传递给 next 来访问该实例。确认导航时将调用回调,并将组件实例作为参数传递给回调:

beforeRouteEnter (to, from, next) {
  next(vm => {
    vm.$root.loading = true;
  })
}
Run Code Online (Sandbox Code Playgroud)


sch*_*max 3

使用 Vue.nextTick 找到了解决方法:

beforeRouteEnter: function(to, from, next) {
    Vue.nextTick(function(){
      // now app is available
      app.loading = true;
      // some loading to happen here...
      seTimeout(function(){            
        app.loading = false;
        next();  
    }, 1000); 
  })
}
Run Code Online (Sandbox Code Playgroud)

感觉有点老套,所以会感谢其他建议。

在这里找到该解决方案的演示: https://s.codepen.io/schellmax/debug/aYvXqx/GnrnbVPBXezr#/foo