nuxt 利用時、URLに hash ( #hoge ) を設定すると同時に、スムーズにするロールするを行いたい場合、一般の方が書いた記事には、to をカラにすればいいと書いてありますが、正しく動作しない条件が存在します。
<div id="note"></div> <nuxt-link to v-scroll-to="'#note'">noteクリック</nuxt-link> <div id="memo"></div> <nuxt-link to v-scroll-to="'#memo'">memoクリック</nuxt-link>
このように記載した上で、URLにハッシュを設定しブラウザをリロード。この状態で、nuxt-link をクリックすると、window.pageYOffset が 0 が入り、スクロール開始位置が間違っているため、とくにスクロール方向が逆になった時に違和感が大きくなってしまいます。フッターに # がついたリンクがあると特に発生しやすいはずです。
vue-scrollto や smooth-scroll が悪いわけではなく、
初回表示時にnuxt-linkをクリックすると、nuxt-link がまず pageYOffset = 0 にスクロール設定することが原因でした。
その後スクロールが開始するため、正し位置からスクロールしません。
対処するためには、以下のように、nuxt-link 代わりの component を作るのがよいのではないでしょうか。
<template lang="pug"> a(:href="to" @click.stop="onClick") slot </template> <script lang="typescript"> import { defineComponent, getCurrentInstance } from '@nuxtjs/composition-api' import TWEEN from '@tweenjs/tween.js' type Props = { path: string, hash: string | null, anker: string, } export default defineComponent({ props: { path: { required: true, type: String }, hash: { type: String }, anker: { required: true, type: String } }, setup ({ path, hash, anker }: Props, { emit }) { const current = getCurrentInstance() const scrollTo = (anker: string) => { const dom = document.querySelector(anker) if (!dom) { return } const end = dom.getBoundingClientRect().top + window.pageYOffset // tween.js の例 const data = { y: window.pageYOffset } new TWEEN.Tween(data) .to({ y: end }, 500) .easing(TWEEN.Easing.Exponential.InOut) .onUpdate(() => { window.scrollTo({ top: data.y }) }) .start() const animate = (time: number) => { if (TWEEN.update(time)) { requestAnimationFrame(animate) } } animate(0) } const to = hash === undefined ? `${path}${anker}` : `${path}${hash}` const onClick = () => { if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) { // do nothing } else if (current?.$route.path === path) { e.preventDefault() window.history.replaceState(null, '', to) scrollTo(anker) } else { e.preventDefault() current?.$router.push(to) } } return { to, onClick } } }) </script>