cordova 检测Vue-Router导航保护中的返回按钮

ryevplcw  于 2022-11-15  发布在  其他
关注(0)|答案(7)|浏览(154)

路线是如何改变的,对我的情况很重要。所以,我想抓住当路线是由浏览器或GSM的后退按钮改变。
这就是我所拥有的:

router.beforeEach((to, from, next) => {
  if ( /* IsItABackButton && */ from.meta.someLogica) {
    next(false) 
    return ''
  }
  next()
})

有没有一些内置的解决方案,我可以使用,而不是IsItABackButton注解?Vue-router本身没有我猜,但任何变通方案也可以在这里工作。或者有没有其他方式更好地识别它?

oknwwptz

oknwwptz1#

这是我找到的唯一方法:
我们可以监听popstate,将其保存在一个变量中,然后检查该变量

// This listener will execute before router.beforeEach only if registered
// before vue-router is registered with Vue.use(VueRouter)

window.popStateDetected = false
window.addEventListener('popstate', () => {
  window.popStateDetected = true
})

router.beforeEach((to, from, next) => {
  const IsItABackButton = window.popStateDetected
  window.popStateDetected = false
  if (IsItABackButton && from.meta.someLogica) {
    next(false) 
    return ''
  }
  next()
})
sycxhyv7

sycxhyv72#

对@yair-levy的回答略有改进。
push封装到自己的navigate方法中并不方便,因为您通常需要从多个位置调用push()。相反,路由器原始方法可以在一个位置进行修补,而无需更改剩余代码。
以下代码是我的Nuxt插件,以防止导航触发后退/前进按钮(用于电子应用程序,以避免后退造成的鼠标额外的“后退”按钮,这使得混乱的电子应用程序)相同的原则可以用于香草Vue和跟踪共同的后退按钮与您的自定义处理。

export default ({ app }, inject) => {
  // this is Nuxt stuff, in vanilla Vue use just your router intances 
  const { router } = app

  let programmatic = false
  ;(['push', 'replace', 'go', 'back', 'forward']).forEach(methodName => {
    const method = router[methodName]
    router[methodName] = (...args) => {
      programmatic = true
      method.apply(router, args)
    }
  })

  router.beforeEach((to, from, next) => {
    // name is null for initial load or page reload
    if (from.name === null || programmatic) {
      // triggered bu router.push/go/... call
      // route as usual
      next()
    } else {
      // triggered by user back/forward 
      // do not route
      next(false)
    }
    programmatic = false // clear flag
  })
}
nom7f22z

nom7f22z3#

正如@Yuci所述,所有路由器钩子回调都是在更新popstate * 之前 * 执行的(因此对本用例没有帮助)
您可以执行的操作:

methods: {
    navigate(location) {
        this.internalNavigation = true;
        this.$router.push(location, function () {
            this.internalNavigation = false;
        }.bind(this));
    }
}

1.用您自己的“导航”函数 Package “router.push”
1.在调用router.push之前,将'internalNavigation'标志设置为true
1.使用vue路由器'oncomplete'回调将internalNavigation标志设置回false
现在,您可以从beforeEach回调中检查标志,并相应地处理它。

router.beforeEach((to, from, next) => {
  if ( this.internalNavigation ) {
      //Do your stufff
  }
  next()
})
lpwwtiir

lpwwtiir4#

我遇到了同样的问题,关于检测后退按钮导航,而不是我的Vue应用程序中的其他类型的导航。
我最终做的是在我真实的的内部应用程序导航中添加一个哈希,以区分预期的应用程序导航和后退按钮导航。
例如,在/page1路径上,我想捕获Back按钮导航以关闭打开的模型。假设我真的想导航到另一个路径,我将向该路径添加一个散列:/page2#force

beforeRouteLeave(to, from, next) {
    // if no hash then handle back button
    if (!to.hash) {
      handleBackButton();
      next(false); // this stops the navigation
      return;
    }
    next(); // otherwise navigate
}

这是相当简单的,但它的工作。你会想检查什么哈希实际上包含如果你使用他们在你的应用程序中超过这一点。

f2uvfpb9

f2uvfpb95#

性能。导航已过时,请注意!https://developer.mozilla.org/en-US/docs/Web/API/Performance/navigation
当你想注册任何全局事件监听器时,你应该非常小心。从注册开始,它每次都会被调用,直到你手动取消注册为止。对我来说,情况是我在创建组件时注册了popstate监听器,以便在以下情况下监听和调用一些操作:

  • 浏览器后退按钮
  • alt +向后箭头
  • 鼠标中的后退按钮

之后,我已经取消注册popstate监听器,以便不在其他组件中调用它,我不希望在其他组件中调用它,请保持代码和方法调用干净:)。
我的代码示例:

created() {
      window.addEventListener('popstate', this.popstateEventAction );
    },
    methods: {
      popstateEventAction() {
        // ... some action triggered when the back button is clicked
        this.removePopstateEventAction();
      },
      removePopstateEventAction() {
        window.removeEventListener('popstate', this.popstateEventAction);
      }
   }

顺祝商祺!

q9yhzks0

q9yhzks06#

被接受的答案 * 几乎 * 对我有效,但我发现听众落后了1点击,可能是由于@Yuci强调的问题。
来自@farincz的答案最适合我,但由于它不是为vanilla Vue编写的,我想我应该在这里写下适合我的答案:

// after createRouter
let programmatic = false;
(['push', 'replace', 'go', 'back', 'forward']).forEach(methodName => {
  const method = router[methodName]
  router[methodName] = (...args) => {
    programmatic = true
    method.apply(router, args)
  }
})

router.beforeEach(async (to, from) => {
  if(!from.name === null || !programmatic) {
    // do stuff you want to do when hitting back/forward or reloading page
  }
  programmatic = false // clear flag
});
ux6nzvsh

ux6nzvsh7#

这很容易做到。

const router = new VueRouter({
  routes: [...],
  scrollBehavior (to, from, savedPosition) {
    if (savedPosition) {
      // History back position, if user click Back button
      return savedPosition
    } else {
      // Scroll to top of page if the user didn't press the back button
      return { x: 0, y: 0 }
    }
  }
})

点击此处查看:https://router.vuejs.org/guide/advanced/scroll-behavior.html#async-scrolling

相关问题