1. emitが効かない
vue-masonryを使用して画像を並べ、そこにモーダル部分をVue.jsのコンポーネントで作成し、クリック時にモーダルが開く機能の実装を目指しています。
開く部分やモーダル内表示は実装できたのですが、モーダル内の「close」ボタンでモーダルを閉じても効きません。当該部分はemitを用いています。
html
1 <div v-masonry-tile class="item" v-for="(item,index) in filteredItems" v-bind:key="item.id" v-on:click="openModal(index)"> 2 <div v-on:mouseleave="!isMobile ? hideOverlay() : null" v-on:mouseover="!isMobile ? showOverlay(index) : null" > 3 <img :src="item.src" :alt="item.altTxt"/> 4 <p class="photo__overlay" v-show="hoverFlag && index === hoverIndex "</p> 5 </div> 6 <modal v-show="modalFlg && index === modalIndex" v-on:close="closeModal" v-bind:modal-id="index" v-bind:modal-data="modalItems"/> 7 </div> 8 </div>
JavaScript
1let app = new Vue({ 2 el: '#app', 3 data: { 4 isMobile : false, 5 hoverFlag: false, 6 hoverIndex: null, 7 modalFlg:false, 8 modalIndex: null, 9 modalItems: [] 10 }, 11 components:{ 12 'modal':{ 13 template : ` 14 <div class="gallery__overlay"> 15 <div class="gallery__modal modal"> 16 <p>これがモーダルウィンドウです。</p> 17 <p v-for="(item,index) in ModalData" v-bind:key="item.id" v-if="currentSlide == index"> 18 <img :src="item.src" :alt="item.altTxt"/> 19 </p> 20 <p @click="$emit('close')"><button>close</button></p> 21 </div> 22 </div> 23 `, 24 props:{ 25 ModalData: Array, 26 ModalId: Number 27 }, 28 data:function(){ 29 return{ 30 currentSlide : this.ModalId 31 } 32 } 33 } 34 }, 35 created: function() { 36 const json_url = "/json/photogallery.json"; 37 //JSONを取得してitemsに格納 38 axios.get(json_url) 39 //成功した場合 40 .then(response => {this.items = response.data;}); 41 }, 42 computed: { 43 filteredItems: function() { 44 //略 45 this.modalItems = this.items; 46 return this.items; 47 } 48 }, 49 methods: 50 closeModal: function(){ 51 this.modalFlg = false; 52 this.modalIndex = null; 53 } 54 } 55});
closeModal関数部分にmodalFlg、modalIndexをconsole.logで出力すると、closeクリック時に問題なく出力されているので、emitによるイベントの受け渡しは成功していると思うのですが、実際のモーダルは閉じません。どういった原因が考えられるでしょうか。
2. 番号リスト
モーダルの一番外側のdivにcloseボタンと同様のイベントを、内部の白い領域にstopPropagationを使用した伝播を防ぐイベントを設定すると、closeボタンのみ効き、モーダルが閉じるようになります。
JavaScript
1components:{ 2 'modal':{//一番目のdiv,二番目のdivに@clickを追加 3 template : ` 4 <div class="gallery__overlay" @click="$emit('close')"> 5 <div class="gallery__modal modal" @click="stopEvent"> 6 ~~ 7 <p @click="$emit('close')"><button>close</button></p> 8 </div> 9 </div> 10 `, 11 methods :{//イベントの伝播を止める 12 stopEvent: function(){ 13 event.stopPropagation() 14 },・・・
このことで望みの動作は実装できているのですが、挙動の理由が分かりません。そのような組み方をした場合、closeボタンと半透明のオーバーレイ部分にてcloseModal関数が発火できるようになると思われるのですが、オーバーレイ部分は反応しません。また、一番外側のdivからイベント設定を外すと、closeボタンのクリックイベントも効かなくなります。どのような原因が考えられるでしょうか。
よろしくお願いいたします。
参考ページは以下です。
https://reffect.co.jp/vue/understand-component-by-moda-window
http://frontendmemo.work/2019-08-13-183000/
回答2件
あなたの回答
tips
プレビュー