Vue Router - 滚动时更改路由中的锚点

Rob*_*Whg 8 javascript url-routing vue.js vue-router

我基本上试图在我的网站上拥有与这里完全相同的路由行为: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 }
    }

Run Code Online (Sandbox Code Playgroud)

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

Ale*_*man 6

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

<div class="section" id="html">
  ...
</div>

<div class="section" id="javascript">
  ...
</div>
Run Code Online (Sandbox Code Playgroud)
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}` })
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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