私はvue.jsでシンプルなコンテキストメニューをコーディングしています。奇妙な要素を右クリックすると、メニューが開きます(@ contextmenu.preventを使用)。これは機能します。
しかし、メニューの外側をクリックすると、メニューが消えます。これは動作しません...私はこれにv-on:blurを使用しています。また、@blurを試しました。それらのどれも動作しません。これが私のhtmlです:
<!-- my context menu -->
<ul class="context-menu"
ref="contextMenuTrack"
v-if="openedMenu === 'contextMenuTrack'"
v-bind:style="{top: top, left: left}"
v-on:blur="closeMenu()">
<li v-on:click="removeTrack(project.structure.tracks.indexOf(targetOfMenu));closeMenu()">delete track</li>
</ul>
<div>
[ ...... stuff here ......]
<!-- Where the menu is called-->
<li class="track"
v-for="track in project.structure.tracks">
<div class="track-name-row">
<li @contextmenu.prevent="openContextMenuTrack(track,$event)"
v-on:click="expandTrack(project.structure.tracks.indexOf(track))"
class="track-color-viewer"></li>
[ .... other li tags .....]
</div>
</li>
[ ...... stuff here ......]
</div>
My Vueコンポーネントのメニューに使用されるデータは次のとおりです:
data() {
return {
//the kind of menu which is opened
openedMenu: undefined,
//the coordinate of the menu
top: "0px",
left: "0px",
//the element which is targeted by the menu
targetOfMenu: undefined
};
},
そして、これが私のVue.jsコンポーネントのメニューに使用されるメソッドです:
methods: {
setMenu(top, left) {
this.top = top - 170 + "px";
this.left = left + "px";
},
// opening menu : calling set menu whith x and y
openContextMenuTrack(track, event) {
this.openedMenu = "contextMenuTrack";
this.targetOfMenu = track;
this.$nextTick((() => {
this.$refs.contextMenuTrack.focus();
this.setMenu(event.y, event.x);
}).bind(this));
},
closeMenu() {
this.openedMenu = undefined;
this.targetOfMenu = undefined;
}
}
blur
evnetはフォームコントロール(<input>
など)。
メニューの外側をクリックしたときにメソッドを実行するcustopmディレクティブを作成することで、問題は通常解決されます。
このような何か:
https://www.npmjs.com/package/v-click-outside
<ul class="context-menu"
ref="contextMenuTrack"
v-if="openedMenu === 'contextMenuTrack'"
v-bind:style="{top: top, left: left}"
v-click-outside="closeMenu()">
<li v-on:click="removeTrack(project.structure.tracks.indexOf(targetOfMenu));closeMenu()">delete track</li>
</ul>
お役に立てれば
編集:
より良いパッケージの例( vue-clickaway ):
これは、推奨されない方法を探している場合に役立ちます;)$ refsは、同じ結果を得るのが難しいでしょう。
let x = document.querySelector('.targetClass).addEventListener('click', (e) =>
{
if(e.target.className == 'targetClass') {
this.close()
}
})
私はプロジェクトでこれをやっただけです:
created: function() {
let self = this;
window.addEventListener("click", function(e) {
if (self.$el.querySelector('.targetClass') && !self.$el.querySelector('.targetClass').contains(e.target)) {
this.close()
}
});
},
destroyed: function(){
let self = this;
window.removeEventListener("click", function(e) {
if (self.$el.querySelector('.targetClass') && !self.$el.querySelector('.targetClass').contains(e.target)) {
this.close()
}
});
},