minor: Improve scrollBehavior to work with transitions, resolve #1376, thanks to @homerjam

This commit is contained in:
Sébastien Chopin 2018-01-31 16:13:28 +01:00
parent 9818116a52
commit 358e2f32fd
2 changed files with 39 additions and 20 deletions

View File

@ -29,6 +29,12 @@ export default {
listeners[key] = transition[key].bind(_parent)
}
})
// Add triggerScroll event on beforeEnter (fix #1376)
let beforeEnter = listeners.beforeEnter
listeners.beforeEnter = (el) => {
window.$nuxt.$emit('triggerScroll')
if (beforeEnter) return beforeEnter.call(_parent, el)
}
let routerView = [
h('router-view', data)

View File

@ -26,27 +26,40 @@ uniqBy(_components, '_name').forEach((route) => { %>const <%= route._name %> = (
<% if (router.scrollBehavior) { %>
const scrollBehavior = <%= serialize(router.scrollBehavior).replace('scrollBehavior(', 'function(').replace('function function', 'function') %>
<% } else { %>
const scrollBehavior = (to, from, savedPosition) => {
// SavedPosition is only available for popstate navigations.
if (savedPosition) {
return savedPosition
} else {
let position = {}
// If no children detected
if (process.client) {
window.history.scrollRestoration = 'manual'
}
const scrollBehavior = function (to, from, savedPosition) {
// if the returned position is falsy or an empty object,
// will retain current scroll position.
let position = false
// if no children detected
if (to.matched.length < 2) {
// Scroll to the top of the page
// scroll to the top of the page
position = { x: 0, y: 0 }
} else if (to.matched.some((r) => r.components.default.options.scrollToTop)) {
// if one of the children has scrollToTop option set to true
position = { x: 0, y: 0 }
}
else if (to.matched.some((r) => r.components.default.options.scrollToTop)) {
// If one of the children has scrollToTop option set to true
position = { x: 0, y: 0 }
// savedPosition is only available for popstate navigations (back button)
if (savedPosition) {
position = savedPosition
}
// If link has anchor, scroll to anchor by returning the selector
if (to.hash) {
return new Promise(resolve => {
// wait for the out transition to complete (if necessary)
window.$nuxt.$once('triggerScroll', () => {
// coords will be used if no selector is provided,
// or if the selector didn't match any element.
if (to.hash && document.querySelector(to.hash)) {
// scroll to anchor by returning the selector
position = { selector: to.hash }
}
return position
}
resolve(position)
})
})
}
<% } %>