【问题标题】:How to create anchor tags with Vue Router如何使用 Vue Router 创建锚标签
【发布时间】:2017-03-13 12:31:37
【问题描述】:

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

我已将id 分配给div 之一,我想拥有这样的锚标签:

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

这是我的路由器配置:

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

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

【问题讨论】:

    标签: javascript html vue.js


    【解决方案1】:

    我相信您是在询问直接跳转到页面的特定区域,方法是导航到页面内的锚标记(如 #section-3)。

    为此,您需要按如下方式修改您的 scrollBehavior 函数:

    new VueRouter({
        mode: 'history',
        scrollBehavior: function(to, from, savedPosition) {
            if (to.hash) {
                return {selector: to.hash}
                //Or for Vue 3:
                //return {el: 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}(或 Vue 3 中的 {el: to.hash}),您会将锚标记哈希传递给下一个路由,该路由将导航到该路由中的相关部分(使用 id 标记)。

    【讨论】:

    • 这仅在历史模式下有效吗?我无法让它工作,但我不在历史模式中
    • 是的,scroll-behavior 页面清楚地提到了这一点。原因是您已经将哈希标识符绑定到路由器状态。不可能有第二个哈希来识别页面位置(滚动到锚点)。另一种选择是在路由中传递query 参数,然后使用普通的旧javascript 滚动到目标页面中的正确位置。我没有一个可行的例子来展示,但我相信如果我们花一些时间就可以做到。
    • 哦,是的,它确实清楚地提到了它。我发誓我对大胆的音符有盲点。谢谢
    • Vue 3 用户的重要提示,xy 也更改为 lefttop next.router.vuejs.org/guide/advanced/scroll-behavior.html
    【解决方案2】:

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

    500ms 的超时是为了让页面加载,因为我发现否则平滑滚动不会滚动到正确的位置(因为页面仍在加载中)。

    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 for Vue 3
        //return {selector: to.hash}
    
        //This does
        return {el: to.hash};
      }
      else if (savedPosition) {
        return savedPosition
      }
      return {top: 0}
    }
    

    【讨论】:

    • 对于 vue 3 return { el: to.hash } 而不是 return { selector: to.hash } 有效。
    • 这似乎确实有效,可惜没有记录!
    【解决方案3】:

    我也刚遇到这个问题,我认为还有一点空间可以优化页面交换。就我而言,我想进行平稳过渡,而不是“跳跃”。我已经在 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 动画正在处理页面滚动,无论是否返回,我都没有任何问题。

    问候 Gkiokan

    【讨论】:

      【解决方案4】:

      如果您需要制作动画 scrollTo,我使用 vue-scrollTo 包:它很容易设置。

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

      【讨论】:

      • 您是否使用 Nuxtjs 进行设置?如果是这样,它是如何完成的?我尝试得到错误意外关键字变量。
      • 不,我没有使用 Nuxtjs。在清除 SSR 时,它的设置非常简单:app.js import VueScrollTo from 'vue-scrollto'; Vue.use(VueScrollTo, { duration: 800, easing: 'ease-in-out', offset: -60, }); 滚动到#element
        你好。我是#元素。
      【解决方案5】:

      我已经尝试过 Adam Reis 的答案,它有效。但是当你刷新页面时,我觉得它与原来的return {selector: to.hash} 相比不太好。所以我尝试了一种不同的方法,使用了 Promise。它的工作方式与原版相同。

      代码如下:

      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)
        })
      }
      

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

      注意:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-25
        • 1970-01-01
        • 2018-06-21
        • 2022-11-30
        • 1970-01-01
        • 2017-06-04
        • 2018-01-19
        相关资源
        最近更新 更多