Vue路由器更改查询参数时防止滚动到顶部
Posted
技术标签:
【中文标题】Vue路由器更改查询参数时防止滚动到顶部【英文标题】:Prevent scrolling to top when vue router changes query params 【发布时间】:2019-10-24 05:47:54 【问题描述】:当我更改路由的查询参数(以及视图的props
)时,如何防止页面滚动到顶部?
我尝试了以下方法,但没有成功:
尝试 1 - 路由的组件
当我将超时设置为任意大的数字(1 秒)时,它会在延迟一段时间后向下滚动。
// in my route's component
props: ...,
watch:
$route(to, from)
let y = window.scrollY;
this.$nextTick(() =>
setTimeout(() =>
console.log(`scrolling to $y`);
window.scrollTo(0, y);
, 0);
);
尝试 2 - $router 的scrollBehavior
这会记录正确的 y
值,但不会保持旧位置。
scrollBehavior(to, from, savedPosition)
if (savedPosition)
return savedPosition;
if (from.path !== to.path)
return x: 0, y: 0 ;
let existing =
x: window.scrollX,
y: window.scrollY
;
console.log(`Existing scroll`, existing);
return new Promise(resolve =>
setTimeout(() =>
resolve(existing);
, 0);
);
,
【问题讨论】:
看来你的组件高度不是在router变化的时候决定的。您的组件中是否有任何异步加载? 【参考方案1】:对其他答案的备注:
1.hashbag: true,
。 hashbag
和 hashbang
在当前版本的 vue-router 文档中都找不到。可能这是一个旧属性。
2.if (to.params.savePosition) return
+ this.$router.push( query: query, params: savePosition: true )
无需使用额外的参数,如 savePosition
来解决此问题。
我对 cmets 的回答:
const router = new VueRouter(
mode: 'history', // or 'hash'
routes,
scrollBehavior (to, from, savedPosition)
// Exists when Browser's back/forward pressed
if (savedPosition)
return savedPosition
// For anchors
else if (to.hash)
return selector: to.hash
// By changing queries we are still in the same component, so "from.path" === "to.path" (new query changes just "to.fullPath", but not "to.path").
else if (from.path === to.path)
return
// Scroll to top
return x: 0, y: 0
)
【讨论】:
【参考方案2】:我刚刚找到了答案。这是我的代码。默认行为将滚动到顶部,除非您传递自定义 params
,如果提供了 path
(https://router.vuejs.org/guide/essentials/navigation.html),路由器将忽略该自定义行为。
scrollBehavior (to, from, savedPosition)
// savedPosition is only available for popstate navigations.
if (savedPosition) return savedPosition
// if the returned position is falsy or an empty object,
// will retain current scroll position.
if (to.params.savePosition) return
// scroll to anchor by returning the selector
if (to.hash)
let position = selector: to.hash
// specify offset of the element
// if (to.hash === '#anchor2')
// position.offset = y: 100
//
return position
// scroll to top by default
return x: 0, y: 0
如果你返回一个 falsy 或一个空对象,Vue 路由器将返回原来的位置。然后,我只需将自定义的params
传递给params
,我使用它的名称为“savePosition”。
this.$router.push( query: query, params: savePosition: true )
这样,除非您将savePosition
传递给params
,或者您传递哈希,否则您的路由器默认会滚动到顶部。
【讨论】:
【参考方案3】:如果您不想在参数更改时滚动到顶部。你可以检查to
和next
那个路径不相等。
scrollBehavior(to, from, savedPosition)
if (to.path != from.path)
return x: 0, y: 0 ;
【讨论】:
【参考方案4】:尝试使用导航守卫
// in your router.js or whatever your router config is
var clientY = 0
router.beforeEach((next) =>
clientY = window.scrollY
next()
)
router.afterEach(() =>
window.scrollTo(0,clientY)
)
【讨论】:
【参考方案5】:有类似的问题,仅在添加模式时对我有用:history 和 hashbag:true。这是 VueRouter 的外观设置:
mode: 'history',
hashbag: true,
scrollBehavior (to, from, savedPosition)
if (savedPosition)
return savedPosition
else
return x: 0, y: 0
,
希望对你有帮助。
【讨论】:
Vue 的路由器不存在hashbag
选项?以上是关于Vue路由器更改查询参数时防止滚动到顶部的主要内容,如果未能解决你的问题,请参考以下文章