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,hashbaghashbang 在当前版本的 vue-router 文档中都找不到。可能这是一个旧属性。

2.if (to.params.savePosition) return + this.$router.push( query: query, params: savePosition: true )

无需使用额外的参数,如 savePosition 来解决此问题。


我对 cme​​ts 的回答:

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】:

如果您不想在参数更改时滚动到顶部。你可以检查tonext那个路径不相等。

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路由器更改查询参数时防止滚动到顶部的主要内容,如果未能解决你的问题,请参考以下文章

vue路由跳转页面滚动到顶部

如何使用反应路由器 dom v6 在路由更改时滚动到顶部?

Vue路由scrollBehavior滚动行为控制锚点

每天一点点之vue框架开发 - vue中使用vue-router切换页面时自动滚动到顶部的方法

Angular 7在子路由更改上禁用滚动到顶部

Angular 5 在每次路线点击时滚动到顶部