【问题标题】:In Vue.js, how do you prevent navigation for a subroute?在 Vue.js 中,如何防止子路由导航?
【发布时间】:2016-10-06 15:51:40
【问题描述】:

beforeRouteLeave 的好处在于您可以防止在某些情况下导航离开。

我有一个使用子路由来呈现部分页面的设置。我想在子路由上设置一个导航守卫,以防止在未保存数据时切换到另一个。

{
    path: '/customers/view',
    component: ViewCustomerShell,
    children: [
        {path: ':id', name: 'ViewCustomer', component: ViewCustomer}
    ]
},

所以当我访问/customers/view/12 并进行更改时,如果他们尝试加载/customers/view/13,我想弹出通常的确认信息并可能停止导航。由于在这种情况下没有调用beforeRouteLeave,所以推荐的防止导航的方法是什么?看$route好像来不及了,因为那时导航已经发生了。

注意:如上所述,beforeRouteLeave 在这种情况下不会被调用;它不起作用。

注意:使用onbeforeunload 不起作用,因为它只会在整个页面发生变化时触发。

【问题讨论】:

    标签: vue.js vue-router


    【解决方案1】:

    我也发布了相同的答案here

    Dynamic route matching 专门设计用于使不同的路径或 URL 映射到相同的路由或组件。因此,从技术上讲,更改参数并不能算作离开(或更改)路线,因此beforeRouteLeave 正确地不会被解雇。

    不过,我建议可以让路由对应的组件负责检测参数的变化。基本上,每当参数更改时,记录更改然后反转它(希望反转速度足够快以至于用户不会注意到它),然后要求确认。如果用户确认更改,则使用您的记录来“取消”更改,但如果用户未确认,则保持原样(不要反转反向)。

    我没有亲自对此进行过测试,因此我不保证它可以正常工作,但希望它能消除关于应用程序的哪个部分负责检查哪些更改的任何困惑。

    【讨论】:

      【解决方案2】:

      我知道这篇文章很老了。但这是我在寻找相同问题时发现的第一个问题。 我不知道现在是否有更好的解决方案,但对于那些正在寻找解决方案的人,我可以分享我的:

      1.定义全局状态

      let isRouteChangeBlocked: boolean = false;
      
      export function blockRouteChange(set?: boolean): boolean {
          if (arguments.length == 1) {
              isRouteChangeBlocked = !!set;
              return isRouteChangeBlocked;
          }
      
          return isRouteChangeBlocked;
      }
      

      2。替换路由函数

      const originalPush = VueRouter.prototype.push;
      VueRouter.prototype.push = function(location: RawLocation) {
          if (blockRouteChange()) {
              if (confirm("Du hast ungespeicherte Änderungen, möchtest du fortfahren?")) {
                  blockRouteChange(false);
                  return originalPush.call(this, location) as any;
              }
              return;
          }
          return originalPush.call(this, location) as any;
      };
      

      3。设置状态

      @Watch("note.text")
      private noteTextChanged() {
          blockRouteChange(true);
      }
      

      这正是我想要的。如果现在有更好的解决方案,请告诉我。您可以在此处获取完整的可运行示例:https://github.com/gabbersepp/dev.to-posts/tree/master/blog-posts/vuejs-avoid-routes/code/example

      【讨论】:

        【解决方案3】:

        您可以在组件中使用$route 对象来观察它是否发生变化,然后启动确认模式...每当您的路线发生变化时都会调用它!

        const Baz = {
          data () {
            return { saved: false }
          },
          template: `
            <div>
              <p>baz ({{ saved ? 'saved' : 'not saved' }})<p>
              <button @click="saved = true">save</button>
            </div>
          `,
        
          watch: {
            '$route': function () {
              if (this.saved || window.confirm('Not saved, are you sure you want to navigate away?')) {
              // do something ...
            }
          }
        }
        

        【讨论】:

        • 正如我在帖子中提到的,beforeRouteLeave 在这种情况下不起作用。
        • 正如我在帖子中提到的,观看 $route 为时已晚,因为那时导航已经发生了。
        • 这仍然是一个问题:无法阻止来自组件的内部导航,有什​​么新信息吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-09-10
        • 2023-04-06
        • 1970-01-01
        • 2021-01-31
        • 1970-01-01
        • 1970-01-01
        • 2020-03-13
        相关资源
        最近更新 更多