【问题标题】:Accessing app inside beforeRouteEnter在 beforeRouteEnter 中访问应用程序
【发布时间】:2018-08-22 21:46:45
【问题描述】:

我想在组件准备由 vue 路由器渲染时在应用根目录中显示一些加载动画。

已经找到this question,建议使用导航守卫,another question,其中接受的答案显示如何使用beforeEach 守卫在app 中设置变量,显示加载动画。

问题在于,在深度链接到某些路由时不起作用(初始 url 包含路由路径,例如 'someurl#/foo')。 beforeEach 守卫根本不会被调用。

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

应用程序:

var app = new Vue({
  el: '#app',
  data: { loading: false }
  router: router
});

组件:

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();
  }
}

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

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

【问题讨论】:

    标签: vue.js vue-router


    【解决方案1】:

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

    beforeRouteEnter 守卫无权访问这个,因为守卫在导航确认之前被调用,因此新的进入组件甚至还没有创建。

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

    beforeRouteEnter (to, from, next) {
      next(vm => {
        vm.$root.loading = true;
      })
    }
    

    【讨论】:

    • 谢谢,我已经找到了,但是在运行 'next()' 时,已经太晚了,因为我不能让路由器等待一些数据加载了跨度>
    【解决方案2】:

    找到使用 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); 
      })
    }
    

    感觉有点hacky,所以感谢其他建议。

    在此处查找此解决方案的演示: https://s.codepen.io/schellmax/debug/aYvXqx/GnrnbVPBXezr#/foo

    【讨论】:

      【解决方案3】:

      如何使用beforeRouteLeave 触发加载,然后让组件在mounted 中将其关闭。

      对于应用程序的初始加载,您可以拥有

      应用

      var app = new Vue({
        el: '#app',
        data() => ({ loading: true }),
        mounted() { this.loading: false },
        router: router
      });
      

      然后为您的组件

      组件

      var Foo = { 
        template: '<div>bar</div>',
        mounted() {
          app.loading = false;
        },
        beforeRouteLeave(to, from , next) {
          switch(to){
            case COMPONENT_TO_SHOW_LOADING_ON:
            case OTHER_COMPONENT:
              app.loading = true;
            default:
          }
        }
      }
      

      【讨论】:

      • 感谢您的回答,但如果我理解正确,我会在这里看到 2 个问题:1) beforeRouteLeave 最初不会在任何组件上被调用(没有组件尚未渲染)和 2) 以这种方式引用其他不相关的组件是某种应该避免的“紧密耦合”
      猜你喜欢
      • 2016-02-29
      • 1970-01-01
      • 1970-01-01
      • 2019-07-06
      • 2012-07-27
      • 2016-08-19
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      相关资源
      最近更新 更多