programing

Vue-Router의 내비게이션가드에서 뒤로 버튼 검출

yoursource 2022. 8. 14. 14:54
반응형

Vue-Router의 내비게이션가드에서 뒤로 버튼 검출

경로를 어떻게 바꾸느냐가 제 경우 중요합니다.그래서 브라우저의 뒤로 버튼이나 gsm으로 루트가 변경되었을 때 잡고 싶습니다.

여기 있습니다.

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

IsItABackButton v? 것 같습니다.Vue-router 자체에는 없는 것 같습니다만, 여기에서는 어떠한 회피책도 사용할 수 있습니다.아니면 그것을 인식할 수 있는 다른 방법이 있을까요?

이게 내가 찾은 유일한 방법이야

팝스테이트를 듣고 변수에 저장한 다음 변수를 체크할 수 있습니다.

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

@Yuci에서 설명한 바와 같이 모든 라우터 훅콜백은 popstate가 갱신되기 전에 실행됩니다(따라서 이 사용 예에서는 도움이 되지 않습니다).

할 수 있는 일:

methods: {
    navigate(location) {
        this.internalNavigation = true;
        this.$router.push(location, function () {
            this.internalNavigation = false;
        }.bind(this));
    }
}
  1. 라우터를 감싼다.사용자 고유의 'push' 기능이 있는 푸시
  2. 라우터를 호출하기 전에를 눌러 'internalNavigation' 플래그를 true로 설정합니다.
  3. vue 라우터 'oncomplete' 콜백을 사용하여 internalNavigation 플래그를 다시 false로 설정합니다.

이제 각 콜백 전에 내부에서 플래그를 확인하고 적절히 처리할 수 있습니다.

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

@yir-levy 답변에 대한 약간의 개선.

★★pushnavigate은 보통 '어느새'라고 부르고 하지 않습니다.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
  })
}

performance.navigation은 권장되지 않습니다.그러니까 https://developer.mozilla.org/en-US/docs/Web/API/Performance/navigation

글로벌 이벤트청취자를 등록하는 경우 매우 주의해야 합니다.이것은 등록 시점부터 메뉴얼의 등록을 취소할 때까지 매번 호출됩니다.이 경우 컴포넌트가 생성되었을 때 popstate listener를 등록하고 다음 경우에 액션을 호출합니다.

  • 브라우저의 뒤로 버튼
  • Alt + 화살표 백
  • 마우스의 뒤로 버튼

를 클릭했습니다.그 후 popstate listener를 등록 해제하고 호출하지 않는 다른 컴포넌트에서는 popstate listener를 호출하지 않도록 합니다.코드 및 메서드콜을 clean : ).

내 코드 샘플:

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

안부 전합니다!

Vue App의 다른 내비게이션과 달리 Back Button 내비게이션 검출에 문제가 있었습니다.

결국 의도된 앱 탐색과 뒤로 버튼 탐색을 구별하기 위해 실제 내부 앱 탐색에 해시를 추가했습니다.

예를 들어 이 루트에서는/page1열려 있는 모델을 닫기 위해 뒤로 버튼 네비게이션을 잡고 싶습니다.정말로 다른 루트로 이동하고 싶다고 상상해 주세요.그 루트에 해시를 추가합니다./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
}

이것은 다소 단순하지만 효과가 있다.앱에서 해시보다 더 많은 해시를 사용하는 경우 해시에 실제로 무엇이 포함되어 있는지 확인해야 합니다.

이것은 아주 쉽게 할 수 있다.

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 를 참조해 주세요.

언급URL : https://stackoverflow.com/questions/51980296/detect-back-button-in-navigation-guards-of-vue-router

반응형