如何使用Vue Router创建锚标签

时间:2016-10-31 12:11:29

标签: javascript html vue.js

我正在创建一个小的Vue webapp,我想在此创建一个锚标记。

我已经iddiv其中一个我希望有这样的锚标签:

<div id="for-home">
   ....
</div>

这是我的路由器配置:

export default new Router({
  abstract: true,
  mode: 'history',
  scrollBehavior: () => ({ y: 0 }),
  routes: [
    { path: '/', component: abcView}
  ]
})

但是这个锚标签有时会起作用,有时候不起作用,我错过了什么吗?

5 个答案:

答案 0 :(得分:30)

我相信您要求直接跳到页面的特定区域,方法是导航到页面中的#section-3等锚标记。

为此,您需要修改scrollBehavior函数,如下所示:

new VueRouter({
    mode: 'history',
    scrollBehavior: function(to, from, savedPosition) {
        if (to.hash) {
            return {selector: to.hash}
        } else {
            return { x: 0, y: 0 }
        }
    },
    routes: [
        {path: '/', component: abcView},
        // your routes
    ]
});

参考:https://router.vuejs.org/guide/advanced/scroll-behavior.html#async-scrolling

我尝试创建一个jsFiddle示例但由于mode:'history'而无效。如果您复制代码并在本地运行,您将看到它的工作原理:https://jsfiddle.net/mani04/gucLhzaL/

通过在scrollBehavior中返回{selector: to.hash},您将把锚标记哈希值传递给下一个路由,该路由将导航到该路由中的相关部分(使用id标记)。

答案 1 :(得分:2)

我刚刚遇到了这个问题,我认为有一点空间来优化页面交换。在我的情况下,我希望顺利过渡,而不是“跳跃”#34;我已经在jQuery中要求作为$的别名。

这是我的路由器设置以获得流畅的动画,可以根据需要随意修改线条。这段代码可以变得更干净,但应该足够精确,以向您展示工作理念。

// Register Router and Paths
const router = new VueRouter({
    mode: 'history',
    routes : [
        { path: '/aboutme/', component: index, name:'me.index'},
        { path: '/aboutme/cv', component: cv, name:'me.cv' }
    ],

    // Build smooth transition logic with $
    scrollBehavior (to, from, savedPosition) {
       if (to.hash) {
          return $('html,body').stop().animate({scrollTop: $(to.hash).offset().top }, 1000);
       } else {
          return $('html,body').stop().animate({scrollTop: 0 }, 500);
       }
    }
})

我身边的问题:我们必须退货吗?由于jQuery Animation正在处理页面滚动,我在返回或不返回时都没有任何问题。

关于Gkiokan

答案 2 :(得分:2)

如果需要制作动画scrollTo,请使用vue-scrollTo软件包:设置非常容易。

可在此处找到有关文档和代码的示例:https://github.com/rigor789/vue-scrollto/

答案 3 :(得分:2)

对我来说,{selector: to.hash}解决方案只是拒绝与vue-router 4.0.0一起使用。以下方法有效,并且还可以实现平滑滚动。

存在500毫秒的超时时间以允许页面加载,因为我发现否则平滑滚动将无法滚动到正确位置(因为页面仍在加载)。

const scrollBehavior = (to, from, savedPosition) => {
  if (to.hash) {
    setTimeout(() => {
      const element = document.getElementById(to.hash.replace(/#/, ''))
      if (element && element.scrollIntoView) {
        element.scrollIntoView({block: 'end', behavior: 'smooth'})
      }
    }, 500)

    //NOTE: This doesn't work
    return {selector: to.hash}
  }
  else if (savedPosition) {
    return savedPosition
  }
  return {top: 0}
}

答案 4 :(得分:0)

我已经尝试过 Adam Reis 的回答,它有效。但是当您刷新页面时,我觉得与原始 function scrollBehavior (to, from, savedPosition) { if (savedPosition) { return savedPosition } if (to.hash) { return new Promise((resolve, reject) => { setTimeout(() => { resolve({ selector: to.hash }) }, 300) }) } return new Promise((resolve, reject) => { setTimeout(() => { resolve({ x: 0, y: 0 }) }, 300) }) } 相比,它有点不太好。所以我通过使用 promise 尝试了不同的方法。它的工作方式与原始方式相同。

代码如下:

scroll-behavior: smooth;

我认为问题是在页面完全加载之前执行了哈希路由。这就是为什么它什么都不做,因为还没有显示带有 id 的元素。但我不知道为什么如果我刷新页面,效果很好。无论如何,这是我的解决方案。希望对新人有所帮助。

注意:

  • 此代码适用于导航到不同页面或同一页面。根据需要调整超时。
  • 为了流畅的导航,我只使用 CSS。在具有滚动的根元素/元素上,您可以添加 {{1}} 以使其平滑,如 MDN 所述。
  • 我使用了 vue-router 3.5.1,因为我仍然使用 Vue 2.x。如果您使用 Vue 3,您可以按照 Adam Reis 的回答中所说的 rits 调整代码。