5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Vue.js で自作した確認ダイアログで、ユーザーの返答を Promise を使って待つ

Last updated at Posted at 2019-07-17

自分用の備忘録的に…

l9xrz-uga97.gif

まず、完成したのはこんなのです。よくあるTODOリストだけど、いちいち確認してくるモーダルのダイアログが追加時と完了設定時に入っています。(メンディ)

素直に実装するなら、TODO追加ボタンのonclickにダイアログの表示処理、ダイアログの「はい」ボタンのonclickにTODO追加の処理を書いていくことになると思います。でもそれだと同じダイアログを別の動作の中で使いまわすのも辛そうですし、後からコードを見た時に一連の動作が追いづらくなりますよね:cry:

そこでこんな実装にしてみました :bulb:

<template>
  <div>
    <form @submit.prevent="doAdd">
      <input type="text" v-model="title">
      <button>add</button>
    </form>
    <ul>
      <li v-for="(todo, i) in todos" :key="i">
        <span class="todo-title" :class="{'done': todo.done}">{{todo.title}}</span>
        <button @click="doMarkAsDone(i)" v-if="!todo.done">done</button>
      </li>
    </ul>
    <div class="modal" v-if="isShowConfirmModal">
      <div class="overlay"></div>
      <div class="modal-container">
        <div class="modal-body">
          <p>マ?</p>
          <button @click="$emit('answerdConfirm', true)">はい</button>
          <button @click="$emit('answerdConfirm', false)">いいえ</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      title: '',
      todos: [],
      isShowConfirmModal: false,
    };
  },
  methods: {
    async doAdd() {
      if (!await this.askConfirm()) return
      this.todos.unshift({
        title: this.title,
        done: false,
      })
      this.title = ''
    },
    async doMarkAsDone(todoIndex) {
      if (!await this.askConfirm()) return
      this.todos = this.todos.map((todo, index) => ({
        ...todo,
        done: index === todoIndex || todo.done,
      }))
    },
    askConfirm() {
      this.isShowConfirmModal = true
      return new Promise(resolve =>
        this.$once('answerdConfirm', confirmValue => {
          this.isShowConfirmModal = false
          resolve(confirmValue)
        })
      )
    },
  },
}
</script>

<style>
...
</style>

いろいろ荒いけど…

ポイントは、確認モーダル表示メソッド( askConfirm() )でモーダルを開きつつ、 Promise を返しているところです。
ユーザーが「はい」か「いいえ」のどちらかをクリックすると、 $emit でイベントが発行され、それを $once が受け取ると、先ほど返した Promise が解決されます。
このようにすることで、TODO追加メソッド( doAdd() )、TODO完了設定メソッド( doMarkAsDone )のどちらでも、処理の一連の流れを分断することなく、ユーザーがダイアログで入力した値を受け取ることができます。

以上!

5
5
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
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?