基礎からメモ: Vue.js CH3-p114 マウント要素外のイベントと操作

スクロールイベントを制御する

マウントした要素の外ではv-onディレクティブが使えない。スクロールイベントなど window や body でのイベントをVueインスタンスから制御するには、addEventListenerなどを使って工夫する。

100pxより下にスクロールしたらページのヘッダーに.compact を付与し、高さを短くする。ページトップに戻すと元のヘッダーの高さにもどる。

<div id="app">
  <header v-bind:class="{ compact: scrolly > 100 }">
    100pxより下にスクロールしたら .compact を付与:
  </header>
  <div id="main"> ............  </div>
</div>
var app = new Vue({
  el: '#app',
  data: {
    scrolly: 0,
    timer: null
  },
  created: function() {
    // ハンドラを登録
    window.addEventListener('scroll', this.handleScroll);
  },
  beforeDestroy: function() {
    // ハンドラを解除(コンポーネントやSPAの場合忘れずに!)
    window.removeEventListener('scroll', this.handleScroll);
  },
  methods: {
    // 違和感ない程度に 200ms 間隔でscrollデータを更新する例
    handleScroll: function() {
      if (this.timer === null) {
        this.timer = setTimeout(function() {
          this.scrolly = window.scrollY;
          clearTimeout(this.timer);
          this.timer = null;
        }.bind(this), 200);
      }
    }
  }
})

スムーススクロールの実装

SmoothScrollライブラリでスムーススクロールを実装する。

ページ下部までスクロールして、「ページ上部へ移動」という文字をクリックするとトップへスムーススクロールする。

<head>
  ........
  <script src="https://cdn.jsdelivr.net/npm/smooth-scroll@14.2.1"></script>
</head>
<body>
  <div id="app">
    <div class="content">
      <p>........</p>
      <p>........</p>
      ...............
    </div>
    <div v-on:click="scrollTop">
      ページ上部へ移動
    </div>
  </div>
var scroll = new SmoothScroll();

var app = new Vue({
  el: '#app',
  methods: {
    scrollTop: function() {
      scroll.animateScroll(0);
    }
  }
})