LoginSignup
2
1

More than 3 years have passed since last update.

vue cliのscroll behavior: アンカーリンクをつくる方法

Last updated at Posted at 2020-03-23

こんにちは。備忘録です。

ページ内にたくさんの記事があるとします。1ページに表示されている記事数は5つ。ところが一番下にある「もっと読む」というボタンをクリックすると、新たに5記事が表示される。そんな動きをしたいとします。

ところがアンカーリンクを設定しなければ、「もっと読む」をクリックしたときにページのトップに連れて行かれてしまいます。UX的には、「もっと読む」をクリックしたときは、トップに飛ばされないまま、続く5つの記事が見たいです。

こんなとき、vue.jsではscroll behaviorという機能を使って、トップに連れて行かれないよう調整することができます。

(下に来る例が上にくる例と違うので紛らわしいのですが、、、)

Step 1. RouterのJSファイルをいじる。

const router = new Router({
  mode: "history",
  scrollBehavior(to, from, savedPosition) { //ここでscrollを調整する。ここにはto, from, savedPositionの三つの引数が入ります。
    if (savedPosition) {
      return savedPosition; //戻る(👈)もしくは進む(👉)ボタンを操作したときは、デフォルトのpositionでロードしてください。
    } else { //そのほかの場合はこのpositionを効かせてちょうだい。
      const position = {};
      if (to.hash) { //hashがあれば……
        position.selector = to.hash; //positionはhashが指定したところだよ。
        if (to.hash === "#animal") { //hashがanimalというidを指定しているのであれば
          position.offset = { y: 200 }; //offsetを効かせてください。※ここはoffsetを効かせていますが、なんでも指定できます。
        }
        if (document.querySelector(to.hash)) { 
          return position;//hashがあれば、そのpositionを教えてください。
        }
        return false; //そもそもhashがなければ、デフォルトの操作をしてください。
      }
    }
  },
routes: [
    {
      path: "/",
      name: "Home",
      component: Home,
      props: true
    }
});

Step 2. Scroll behavior を効かせたい instance/componentをいじる。

<section class="zoo-information">
      <h1>Our Zoo</h1>
      <p>{{zoo.description}}</p>
</section>

<section class="animals">
      <h2>I think {{ animal.name }} is the best</h2>
      <div class="cards" id="animal"> 
        <div v-for="animal in animals" :key="animal.slug" class="card">
          <router-link
            :to="{
              name: 'animalDetails',
              params: { animalSlug: animal.slug},
              hash: '#animal'
          }"
          > //ここにクリックしたとき、トップに行かず、#animalのところで位置をキープしたい
            <img :src="require(`@/assets/${animal.image}`)" :alt="animal.name" />
            <span class="card__text">{{ animal.name }}</span>
          </router-link>
        </div>
      </div>
      <router-view :key="$route.path" />
    </section>

何も設定しなければ、router-linkのリンクをクリックしたとき、.zoo-informationがトップにくるようページが表示されるでしょう。でも、せっかくrouter-linkをクリックしているので、UX的にもrouter-linkをクリックしたときはrouter-linkの中身がページのトップにくるよう表示したいです。

そこでto.hashをrouter.jsで指定しておくと、router-linkをクリックしたときにid="animal"と書かれた部分がページのトップにくるよう位置を指定できるのです。

なかなかのツワモノです。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1