Без добавления дополнительных зависимостей в ваш проект
Недавно я столкнулся с этой проблемой, когда у меня был тумблер для отображения меню, но когда я щелкнул другую часть страницы, меню не исчезло. Я понял, что существуют библиотеки, такие как эта https://github.com/simplesmiler/vue-clickaway, но я бы предпочел не использовать другую зависимость, если в этом нет необходимости. Я думал, что поделюсь одним беззависимым способом скрыть меню, когда пользователь щелкает от переключателя.
В новом проекте vue я начал с простого переключателя, который показывает или скрывает меню:
Чтобы получить простое меню переключения выше, я изменил App.vue
на это:
<template> <div class="toggle-container"> <button class="toggle" @click="toggle = !toggle">Toggle</button> <div v-if="toggle"> Menu </div> </div> </template>
<script> export default { data () { return { toggle: false } }, } </script>
<style scoped> .toggle-container { position: fixed; top: 50%; left: 50%; } </style>
Это демонстрирует проблему - «Щелчок» на переключателе, когда меню открыто, не скроет меню снова.
Решение
Мы можем добавить прослушиватель событий для прослушивания события щелчка при создании компонента и один для случая, когда компонент отключен:
created() {
window.addEventListener('click', this.close)
},
beforeUnmount() {
window.removeEventListener('click', this.close)
},
Затем в событии закрытия мы можем проверить, была ли нажата кнопка переключения или вне ее, проверив this.$el
(корневой элемент DOM):
close(e) {
if (! this.$el.contains(e.target)) {
this.active = false
}
}
Вот как выглядит мой последний App.vue
файл:
<template> <div class="toggle-container"> <button class="toggle" @click="active = ! active">Toggle</button> <div v-if="active"> Menu </div> </div> </template>
<script> export default { data () { return { active: false } },
created() { window.addEventListener('click', this.close) }, beforeUnmount() { window.removeEventListener('click', this.close) },
methods: { close(e) { if (! this.$el.contains(e.target)) { this.active = false } } } } </script>
<style scoped> .toggle-container { position: fixed; top: 50%; left: 50%; } </style>
Мне лично нравится это решение, потому что оно довольно простое и позволяет избежать дополнительных зависимостей. Надеюсь, это поможет вам в вашем проекте!