【问题标题】:Vue Router - Change anchor in route on scrollVue Router - 在滚动时更改路由中的锚点
【发布时间】:2020-08-22 00:10:55
【问题描述】:

我基本上试图在我的网站上使用与此处完全相同的路由行为:https://router.vuejs.org/guide/#html。 请注意,当您向下滚动时,链接会更改为 https://router.vuejs.org/guide/#javascript。向上滚动,反之亦然。重新加载页面时,您的位置会被保存。

我在路由器中添加了以下滚动行为:

  scrollBehavior(to, from, savedPosition) {
    if (to.hash) {
        return { selector: to.hash }
    } else if (savedPosition) {
        return savedPosition;
    } else {
        return { x: 0, y: 0 }
    }

现在我可以跳转到带有链接的锚点,并且路线会发生变化。这就是我所得到的。选择 Vue Router 网站作为示例有点讽刺,但无论如何 - 我怎样才能复制它的行为?

【问题讨论】:

    标签: javascript vue.js url-routing vue-router


    【解决方案1】:

    您可以设置IntersectionObserver 并观察页面上的所有部分。当一个部分进入视图时,获取该部分的 id 并更新路由:

    <div class="section" id="html">
      ...
    </div>
    
    <div class="section" id="javascript">
      ...
    </div>
    
    data () {
      return {
        sectionObserver: null
      }
    },
    mounted () {
      this.observeSections()
    },
    methods: {
      observeSections() {
        try {
          this.sectionObserver.disconnect()
        } catch (error) {}
    
        const options = {
          rootMargin: '0px 0px',
          threshold: 0
        }
        this.sectionObserver = new IntersectionObserver(this.sectionObserverHandler, options)
      
        // Observe each section
        const sections = document.querySelectorAll('.section')
        sections.forEach(section => {
          this.sectionObserver.observe(section)
        })
      },
      sectionObserverHandler (entries) {
        for (const entry of entries) {
          if (entry.isIntersecting) {
             const sectionId = entry.target.id
             // Push sectionId to router here 
             this.$router.push({ name: this.$route.name, hash: `#${sectionId}` })
          }
        }
      }
    }
    

    正如评论中提到的@Sigi,您可以在sectionObserverHandler 中使用this.$router.replace() 而不是this.$router.push(),以避免混淆历史记录。

    【讨论】:

    • 很好的答案!在sectionObserverHandler 中使用this.$router.replace() 而不是push() 可能会更好,以避免混淆历史记录。
    • 为什么不把 this.sectionObserver.disconnect() 放到 beforeDesctroy() 生命周期方法中呢?使用这样的 try/catch 似乎有点笨拙。
    • @MichaelGiovanniPumo 我没有尝试过你的方法,但我不确定它是否适用于所有情况,我认为这种方法更安全一些。我记得有一种情况,我需要多次初始化/重置观察者,在这种情况下,在 beforeDesctroy 上重置一次是行不通的
    猜你喜欢
    • 2021-03-20
    • 1970-01-01
    • 1970-01-01
    • 2018-02-17
    • 2021-02-06
    • 2017-12-10
    • 2018-08-03
    • 2018-03-06
    相关资源
    最近更新 更多