ボタンをクリックするとドロップダウンメニューを表示/非表示できるHeaderSubmenuコンポーネントがあります。さて、ユーザーがアプリ内のどこかをクリックしてもこのドロップダウンメニューではクリックしないと、それを隠すための良い解決策を見つけようとしています。他の場所をクリックしたときのコンポーネントのトリガー方法
私はVuexとVueRouterでVue 2.3.3を使用しています。
私のアプリのエントリポイント:
'use strict';
import Vue from 'vue';
import VueRouter from 'vue-router';
import Vuex from 'vuex';
Vue.use(VueRouter);
Vue.use(Vuex);
import store_data from 'store';
import {router} from 'routes';
import App from 'app.vue';
var store = new Vuex.Store(store_data);
new Vue({
el: '#app',
store,
router: router,
render: function (createElement) {
return createElement(App)
}
})
テンプレートのHeaderSubmenu
コンポーネント:
<template>
<li class="header-submenu">
<!-- button to show/hide the drop-down menu -->
<header-link v-bind="$props" :href="to ? false : '#'" @click.native="toggleMenu()">
<slot name="item"></slot>
</header-link>
<!-- drop-down menu -->
<ul class="submenu-list" :class="{'open': open, 'animated': animated}" @animationend="displaynone()">
<slot></slot>
</ul>
</li>
</template>
このコンポーネントは、私のアプリのどこかで、ユーザーが他の場所よりもクリックしたときに、私は彼のtoggleMenu()
メソッドを呼び出したいです<ul class="submenu-list">
にあります。
私はドロップダウンメニューを「登録」し、自分のアプリケーション上のグローバル@clickイベントを検出するグローバルイベントバスを考えました。登録されたメニューがクリックされた要素でない場合、私たちはtoggleMenu()
メソッドを呼び出すでしょう。 (理想的には、同じ動作をする他の要素を登録することができます)
...しかし、私はvueイベントシステムをまったくマスターしません。 イベントが一部の要素にないかどうかを確認する方法はありますか? これを達成する方法はわかりません。手伝って頂けますか ?ありがとうございました !
====== ====== EDIT
バート・エヴァンスの助けを借りて、私はこのカスタムディレクティブを使用:
// directive-clickoutside.js
export default {
bind(el, binding, vnode) {
el.event = function (event) {
// here I check that click was outside the el and his childrens
if (!(el == event.target || el.contains(event.target))) {
// and if it did, call method provided in attribute value
vnode.context[binding.expression](event);
}
};
document.body.addEventListener('click', el.event)
},
unbind(el) {
document.body.removeEventListener('click', el.event)
},
};
// main.js
import clickout from 'utils/directive-clickoutside';
Vue.directive('clickout', clickout);
私は私のコンポーネントテンプレートでこれを使用:
// HeaderSubmenu component
<template>
<li class="header-submenu">
<!-- élément du header servant à ouvrir le sous-menu -->
<header-link v-bind="$props" :href="to ? false : '#'" @click.native="toggle()">
<slot name="item"></slot>
</header-link>
<!-- sous-menu -->
<ul class="submenu-list" :class="{'open': open, 'animated': animated}" @animationend="displaynone()" v-clickout="hide()">
<slot></slot>
</ul>
</li>
</template>
しかし、私はページ上の任意の場所をクリックすると、このコードは失敗します。
Uncaught TypeError: n.context[e.expression] is not a function
at HTMLBodyElement.t.event (directive-clickoutside.js:7)
どこに問題がありますか?
[外部の要素を検出する]の複製があります。(https://stackoverflow.com/questions/36170425/detect-click-outside-element) – Bert
ありがとう、私はカスタムディレクティブを使用しようとしましたが、無限で終了しますループを更新する。私はあなたにそれを示すために投稿を編集しました。 – Thaledric
'toggleMenu'は何をしますか? – Bert