———–2020/5/14 追記———–
簡単に支えてカスタマイズ性もあるライブラリを見つけたのでこれで良い気がする、、
https://sweetalert2.github.io/#examples
———–追記終わり———–
Vue.js でポップアップを自作してみたのでやり方をメモしておきます。
(ポップアップというかモーダルウインドウ?ダイアログウインドウ?何が正式名称のかよく分かりませんがここではポップアップと呼びます。)
最初はサボってこのライブラリ使ってたんですけど
https://www.npmjs.com/package/vuejs-dialog
やっぱり細かい CSS とか動きとか調整しようとすると自作の方が都合が良いんですよね。
環境
- Mac Mojave: 10.14.5
- vue: 2.6.7
- vuex: 3.1.0
表示制御
App.vue に以下を追加します。
showModalDialog
のオンオフで表示制御します。
showModalDialog
はコンポーネントをまたぐのでvuex
を利用します。
1 2 3 4 5 6 7 8 9 10 11 12
| <template> <div id="app">
<ModalDialog v-if="$store.state.showModalDialog"> </ModalDialog>
<router-view /> </div> </template>
<script>
|
ポップアップコンポーネント作成
上のModalDialog
で表示されるコンポーネントを作成します。
いいえを押した場合は単にポップアップを閉じるだけで、
はいを押した場合はコールバック関数を実行します。
/src/components/ModalDialog.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
| <template> <transition name="modal"> <div class="modal-mask"> <div class="modal-wrapper"> <div class="modal-container"> <div class="modal-header"></div>
<div class="modal-body"> {{$store.state.modal_msg}} </div>
<div class="btns"> <button class="btn" @click="$store.commit('set_showModalDialog', false);" > キャンセル </button> <button class="btn" @click="do_yes()"> OK </button> </div> </div> </div> </div> </transition> </template>
<script> export default { name: 'ModalDialog', methods: { do_yes() { this.$store.state.callback_func() this.$store.commit('set_showModalDialog', false) } } } </script>
<style scoped> .modal-mask { position: fixed; z-index: 9998; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); display: table; transition: opacity 0.3s ease; } .modal-wrapper { display: table-cell; vertical-align: middle; } .modal-container { width: 300px; margin: 0px auto; background-color: #fff; border-radius: 5px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33); transition: all 0.3s ease; } .modal-header { display: block; text-align: center; border: 0px; padding: 20px 0 0 0; font-weight: bold; } .modal-body { display: block; text-align: center; padding: 5px 15px 0 15px; border: 0px; font-size: 0.9rem; } .btns { display: inline-block; margin-top: 15px; width: 300px; } .btn { width: 50%; border-top: 1px solid #ddd; color: rgb(66, 133, 245); height: 50px; font-weight: bold; } .btn + .btn { border-left: 1px solid #ddd; }
/* * The following styles are auto-applied to elements with * transition="modal" when their visibility is toggled * by Vue.js. * * You can easily play with the modal transition by editing * these styles. */
.modal-enter { opacity: 0; } .modal-leave-active { opacity: 0; } .modal-enter .modal-container, .modal-leave-active .modal-container { -webkit-transform: scale(1.1); transform: scale(1.1); } </style>
|
グローバルコンポーネントとして登録
ModalDialog
をコンポーネントとして利用できるように
src/main.js
に以下の行を追加します。
1 2 3
| import ModalDialog from '@/components/ModalDialog' Vue.component('ModalDialog', ModalDialog)
|
vuex の store の設定
表示のオンオフの変数と表示内容とコールバック関数を設定します。
/src/store.js
を以下の通り修正する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| export default { strict: true, namespaced: true, state: { showModalDialog: false, modal_msg: '', callback_func: null }, mutations: { set_showModalDialog(state, showModalDialog) { state.showModalDialog = showModalDialog }, set_modal_msg(state, modal_msg) { state.modal_msg = modal_msg }, set_callback_func(state, callback_func) { state.callback_func = callback_func } } }
|
ポップアップを表示する
使いたい画面に以下のshow_dialog
関数を追加して、これを実行すれば表示されるはずです!
1 2 3 4 5 6 7 8 9 10 11
| methods: { show_dialog() { this.$store.commit("set_showModalDialog", true); this.$store.commit("set_modal_msg", "本当に削除しますか?"); this.$store.commit("set_callback_func", this.callback_func); }, callback_func() { console.log('コールバック関数が実行されました') } }
|
終わりに
最初は少し手間ですが一度やっておくと使い回しは簡単なので早めにやっておくとお得な感じです。
ではでは、よきポップアップライフを。
以上です。