InfoMenu1-Bad
by Chige12
HTML
<div id="app">
<div class="containter">
<p>問題1 メニューが閉じない場合がある</p>
<msg-comp
v-for="msg in msgList"
:msg="msg"
></msg-comp>
</div>
</div>
<script type="text/x-template" id="message">
<div class="msg">
<button v-on:click.stop="showInfo = !showInfo">Info {{msg}}</button>
<info-menu
v-if="showInfo"
v-on:close="showInfo = false">
</info-menu>
</div>
</script>
<script type="text/x-template" id="info">
<div class="info">
<button>AAA</button>
<button>BBB</button>
<button>CCC</button>
</div>
</script>
CSS
.msg {
position: relative;
border: 1px solid blue;
width: 60px;
margin: 4px;
padding: 4px;
background: #fff;
}
.info {
position: absolute;
top: 0;
left: 72px;
background: #fff;
border: 1px solid red;
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
padding: 5px;
}
Vue
var listener = {
methods:{
listen :function(target, eventType, callback) {
if (!this._eventRemovers){
this._eventRemovers = [];
}
target.addEventListener(eventType, callback);
this._eventRemovers.push( {
remove :function() {
target.removeEventListener(eventType, callback)
}
})
}
},
destroyed:function(){
if (this._eventRemovers){
this._eventRemovers.forEach(function(eventRemover){
eventRemover.remove();
});
}
}
}
Vue.component('info-menu', {
mixins:[listener],
template: '#info',
created:function(){
this.listen(window, 'click', function(e){
if (!this.$el.contains(e.target)){
this.$emit('close');
}
}.bind(this));
}
});
Vue.component('msg-comp', {
template: '#message',
props: ['msg'],
data() {
return {
showInfo: false
}
}
});
new Vue({
el: '#app',
data: {
msgList: [
1, 2, 3
]
}
})