エスケープでモーダルを閉じる

内容

  • esc キーでモーダルを閉じたいので方法を調べた。
  • コンポーネントの生成時に keyupaddEventListener する
  • esc キーの時に $emit('close') 的なことをする

ソース

github.com

vuejsでモーダルを表示する、閉じる ソースからかいつまんで話します リポジトリの内容を実行して動き見るほうが早いと思う

  1. モーダルを出す

modalを置いたコンポーネント

<template>
  <div>
    <!-- v-ifで表示 -->
    <button @click="showModal">show</button>
    <!-- v-ifで表示モーダル用のコンポーネントを表示 -->
    <modal v-if="show"/>
  </div>
</template>

<script>
import Modal from './Modal.vue'
export default {
  name: 'CloseModal',
  methods: {
    showModal() {
      this.show = true
    },
  },
  components: {
    Modal
  }
}
</script>

modalコンポーネント

<template>
  <div class="overlay">
    なにか適当な内容
  </div>
</template>

<script>
export default {
  name: 'Modal',
}
</script>

<style scoped>
.overlay {
  position: fixed;
  top: 0;
  left: 0;
  background: rgba(0,0,0, .5);
  z-index:10;
  height:100%;
  width: 100%
}
.content {
  background: white;
  width: 100px;
  height: 100px;
  position: relative;
  left: 43%;
  top: 43%;
}
</style>
  1. クローズボタンを設置

modalを置いたコンポーネント

<template>
  <div>
    <button @click="showModal">show</button>
    <!-- closeModalをpropsで渡す -->
    <modal v-if="show" :closeModal="closeModal"/>
  </div>
</template>

<script>
import Modal from './Modal.vue'
export default {
  name: 'CloseModal',
  data() {
    return {
      show: false
    }
  },
  methods: {
    showModal() {
      this.show = true
    },
    // モーダル閉じるメソッド
    closeModal() {
      this.show = false
    }
  },
  components: {
    Modal
  }
}
</script>

modalコンポーネント

<template>
  <div class="overlay">
    <div class="content">
      <!-- clickでpropsで受けたモーダル閉じるメソッドを実行 -->
      <button @click="closeModal">close</button>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Modal',
  props: {
    closeModal: Function
  },
}
</script>

<style scoped>
/* 省略 */
</style>

  1. モーダルの外クリックで閉じる

modalを置いたコンポーネント

// 変更なし

modalコンポーネント

<template>
  <!-- @clickを同じように設定する -->
  <div class="overlay" @click="closeModal">
    <div class="content">
      <button @click="closeModal">close</button>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Modal',
  props: {
    closeModal: Function
  },
}
</script>

<style scoped>
/* 省略 */
</style>

  1. エスケープで閉じる modalを置いたコンポーネント
// 変更なし

modalコンポーネント

<template>
  <div class="overlay" @click="closeModal">
    <div class="content">
      <button @click="closeModal">close</button>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Modal',
  props: {
    closeModal: Function
  },
  created() {
    // createdでkeyupをイベントリスナーに追加
    document.addEventListener('keyup', this.close)
  },
  destroyed() {
    // モーダルが消える際にイベントリスナーを破棄
    document.removeEventListener('keyup', this.close)
  },
  methods: {
    close(e) {
      // e.codeでescapeを判断
      if (e.code === 'Escape') {
        this.closeModal()
      }
    }
  }
}
</script>

<style scoped>
/* 省略 */
</style>