From 1563c3c1a0077a4fd8de9a57f268023be2879788 Mon Sep 17 00:00:00 2001 From: James Homer Date: Thu, 12 Oct 2017 19:18:03 +0100 Subject: [PATCH 1/3] Call scrollBehavior with app context This allows us to listen for events in the scroll behavior hook, thus enabling us to resolve a promise returned by the hook upon triggering of some custom event (for example one emited on the $root by an after-leave transition event). --- src/util/scroll.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/scroll.js b/src/util/scroll.js index 9991adaa7..592d99757 100644 --- a/src/util/scroll.js +++ b/src/util/scroll.js @@ -39,7 +39,7 @@ export function handleScroll ( // wait until re-render finishes before scrolling router.app.$nextTick(() => { const position = getScrollPosition() - const shouldScroll = behavior(to, from, isPop ? position : null) + const shouldScroll = behavior.call(router.app, to, from, isPop ? position : null) if (!shouldScroll) { return From 36f7e19edc297c848e11230ff2c0401bedf34421 Mon Sep 17 00:00:00 2001 From: James Homer Date: Fri, 13 Oct 2017 12:14:46 +0100 Subject: [PATCH 2/3] Update scrollBehavior example --- examples/scroll-behavior/app.js | 48 ++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/examples/scroll-behavior/app.js b/examples/scroll-behavior/app.js index e4c40d057..993c7ca56 100644 --- a/examples/scroll-behavior/app.js +++ b/examples/scroll-behavior/app.js @@ -25,23 +25,27 @@ const scrollBehavior = function (to, from, savedPosition) { // savedPosition is only available for popstate navigations. return savedPosition } else { - return new Promise(resolve => { - const position = {} - let delay = 500 - // new navigation. - // scroll to anchor by returning the selector - if (to.hash) { - position.selector = to.hash + const position = {} + + // scroll to anchor by returning the selector + if (to.hash) { + position.selector = to.hash - // specify offset of the element - if (to.hash === '#anchor2') { - position.offset = { y: 100 } - } + // specify offset of the element + if (to.hash === '#anchor2') { + position.offset = { y: 100 } + } - if (document.querySelector(to.hash)) { - delay = 0 - } + if (document.querySelector(to.hash)) { + return position } + + // if the returned position is falsy or an empty object, + // will retain current scroll position. + return false + } + + return new Promise(resolve => { // check if any matched route config has meta that requires scrolling to top if (to.matched.some(m => m.meta.scrollToTop)) { // coords will be used if no selector is provided, @@ -49,12 +53,13 @@ const scrollBehavior = function (to, from, savedPosition) { position.x = 0 position.y = 0 } + // wait for the out transition to complete (if necessary) - setTimeout(() => { - // if the returned position is falsy or an empty object, + this.$root.$once('triggerScroll', () => { + // if the resolved position is falsy or an empty object, // will retain current scroll position. resolve(position) - }, delay) + }) }) } } @@ -82,9 +87,14 @@ new Vue({
  • /bar#anchor
  • /bar#anchor2
  • - + - ` + `, + methods: { + afterLeave () { + this.$root.$emit('triggerScroll') + } + } }).$mount('#app') From ed4ad32cb2dc1d93b5b04ef98434dbd63145fb87 Mon Sep 17 00:00:00 2001 From: James Homer Date: Wed, 18 Oct 2017 10:50:27 +0100 Subject: [PATCH 3/3] change scrollBehavior context to router --- examples/scroll-behavior/app.js | 2 +- src/util/scroll.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/scroll-behavior/app.js b/examples/scroll-behavior/app.js index 993c7ca56..4f1bbb3d1 100644 --- a/examples/scroll-behavior/app.js +++ b/examples/scroll-behavior/app.js @@ -55,7 +55,7 @@ const scrollBehavior = function (to, from, savedPosition) { } // wait for the out transition to complete (if necessary) - this.$root.$once('triggerScroll', () => { + this.app.$root.$once('triggerScroll', () => { // if the resolved position is falsy or an empty object, // will retain current scroll position. resolve(position) diff --git a/src/util/scroll.js b/src/util/scroll.js index 592d99757..cceb03640 100644 --- a/src/util/scroll.js +++ b/src/util/scroll.js @@ -39,7 +39,7 @@ export function handleScroll ( // wait until re-render finishes before scrolling router.app.$nextTick(() => { const position = getScrollPosition() - const shouldScroll = behavior.call(router.app, to, from, isPop ? position : null) + const shouldScroll = behavior.call(router, to, from, isPop ? position : null) if (!shouldScroll) { return