问题
I have a page transition that doesn't work nicely when the scroll to the top of a new route is instant. I'd like to wait 100ms before it automatically scrolls to the top. The following code doesn't end up scrolling at all. Is there a way to do this?
export default new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'Home',
component: Home
}
],
scrollBehavior (to, from, savedPosition) {
setTimeout(() => {
return { x: 0, y: 0 }
}, 100);
}
})
回答1:
This is natively supported by Vue now, use scrollBehaviour
, like this:
export default new Router({
scrollBehavior() {
return { x: 0, y: 0 };
},
routes: [
{
path: '/',
name: 'Home',
component: Home
}
],
mode: 'history'
});
More here.
回答2:
The other answers fail to handle edge cases such as:
- Saved Position - The saved position occurs when the user clicks the back or forward positions. We want to maintain the location the user was looking at.
- Hash Links - E.g.
http://example.com/foo#bar
should navigate to the element on the page with anid
ofbar
. - Finally, in all other cases we can navigate to the top of the page.
Here is the sample code that handles all of the above:
const router = new VueRouter({
mode: "history",
base: process.env.BASE_URL,
routes,
scrollBehavior: (to, from, savedPosition) => {
if (savedPosition) {
return savedPosition;
} else if (to.hash) {
return {
selector: to.hash
};
} else {
return { x: 0, y: 0 };
}
}
});
回答3:
If you want this to happen on every route, you can do so in the before hook in the router:
const router = new VueRouter({ ... })
router.beforeEach(function (to, from, next) {
setTimeout(() => {
window.scrollTo(0, 0);
}, 100);
next();
});
If you are on an older version of vue-router, use:
router.beforeEach(function (transition) {
setTimeout(() => {
window.scrollTo(0, 0);
}, 100);
transition.next();
});
回答4:
When using client-side routing, we may want to scroll to top when navigating to a new route, or preserve the scrolling position of history entries just like real page reload does. vue-router allows you to achieve these and even better, allows you to completely customize the scroll behavior on route navigation.
Note: this feature only works if the browser supports history.pushState
.
scrollBehavior (to, from, savedPosition) {
return { x: 0, y: 0 }
}
With Saved Position:
scrollBehavior (to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
return { x: 0, y: 0 }
}
}
For more information
回答5:
This is probably not the best way, but adding
document.body.scrollTop = document.documentElement.scrollTop = 0;
in a route's core component's (in this case, Home
) mounted()
function achieves what I want.
回答6:
If you want to wait a long time use Async Scrolling of scrollBehaviour
, like this:
export default new Router({
scrollBehavior() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ x: 0, y: 0 })
}, 100)
})
},
routes: [
{
path: '/',
name: 'Home',
component: Home
}
],
mode: 'history'
});
More here.
来源:https://stackoverflow.com/questions/42538449/vue-js-scroll-to-top-of-new-page-route-after-settimeout