Что такое Vue.js?
Vue.js — это JavaScript-фреймворк для создания пользовательских интерфейсов. Он строится на основе стандартных HTML, CSS и JavaScript и предоставляет декларативную и основанную на компонентах модель программирования, которая помогает вам эффективно разрабатывать пользовательские интерфейсы, будь то простые или сложные.
Наша проблема заключается в том, чтобы скрыть компонент, когда пользователь щелкает за его пределами, будь то случайным образом на странице, на другом элементе или на компоненте.
Это обычно используется на веб-страницах для обеспечения лучшего взаимодействия с пользователем.
Решение
Хитрость заключается в том, чтобы добавить прослушиватель событий щелчка ко всей DOM и проверять при каждом щелчке, было ли событие щелчка вызвано нашим элементом или другим элементом в DOM.
давайте посмотрим на этот пример:
Во-первых, давайте создадим простую панель навигации, которая показывает некоторые параметры при нажатии:
Мы создадим компонент vue и назовем его NavIcon.vue.
Исходный код NavIcon.vue:
<script setup> function toggleNav(e){ e.target.classList.toggle("open") } </script> <template> <div class="menu" @click="toggleNav"> <div class="button"></div> <div class="button"></div> <div class="button"></div> </div> </template>
Класс «open» отвечает за отображение или скрытие параметров навигации.
Для стиля я использую Sass, препроцессорный язык сценариев, который интерпретируется в CSS. Он содержит меньше кода, поэтому вы можете писать CSS быстрее.
Стиль компонента:
<style lang="scss"> $icon-bg-color : #fdfdff; html { background: #c7c7fc; height: 100vh; display: grid; place-content: center; -webkit-tap-highlight-color: transparent; } .menu { position: relative; top: 40px; padding: 30px; background: $icon-bg-color; border-radius: 100%; cursor: pointer; &::before, &::after { content: ""; background: #c3c2c7; border-radius: 5px; width: 30px; height: 5px; position: absolute; left: 16px; top: 27px; transition: 0.2s ease; z-index: 1; } &::before { transform: rotate(0deg); } &::after { transform: rotate(-90deg); } &.open { opacity: .9; &::before { transform: rotate(45deg); } &::after { transform: rotate(-45deg); } .button { opacity: 1; pointer-events: auto; &:first-of-type { bottom: 40px; right: 70px; background: url("https://bassets.github.io/cam.svg") no-repeat 50%/50% $icon-bg-color; } &:nth-of-type(2) { bottom: 80px; background: url("https://bassets.github.io/img.svg") no-repeat 50%/ 50% $icon-bg-color; transition-delay: .05s; } &:last-of-type { bottom: 40px; right: -70px; background: url("https://bassets.github.io/music.svg") no-repeat 50% 45%/50% 45% $icon-bg-color; transition-delay: .1s; } } } } .button { padding: 30px; border-radius: 50%; cursor: pointer; background: #e8e8f3; position: absolute; bottom: 0; right: 0; opacity: 0; pointer-events: none; box-shadow: inherit; transition: 0.2s cubic-bezier(0.18, 0.89, 0.32, 1.28), 0.2s ease opacity, 0.2s cubic-bezier(.08,.82,.17,1) transform; &:hover { transform: scale(1.1); } } </style>
Компонент будет выглядеть так:
Обратите внимание, навигация скрыта только тогда, когда я нажимаю кнопку закрытия.
Мы хотим, чтобы он закрывался всякий раз, когда делается щелчок за пределами навигации.
Для этого мы добавим обработчик событий с обратным вызовом в документ дыры после того, как компонент будет полностью смонтирован в браузере.
При выполнении клика вызывается обратный вызов.
Обратный вызов имеет условие того, был ли щелчок от «div» или от одного из его дочерних элементов. В этом случае ничего делать не будем, Если условие ложно, то уберем из div класс «open», в ответ пропадет навигация.
Для этого нам нужно добавить следующий код:
Исходный код NavIcon.vue:
<script setup> import { onMounted, ref } from "vue" const navIcon = ref(null) onMounted(()=>{ document.addEventListener("click", (e)=>{ if(e.target == navIcon.value || e.target.parentNode == navIcon.value) return navIcon.value.classList.remove("open") }) }) function toggleNav(e){ e.target.classList.toggle("open") } </script> <template> <div class="menu" @click="toggleNav" ref="navIcon"> <div class="button"></div> <div class="button"></div> <div class="button"></div> </div> </template>
Я использовал параметр ref, чтобы получить div из DOM, и хук onMounted, который регистрирует обратный вызов, который будет вызываться после монтирования компонента.
Результат:
Поздравляем, теперь мы успешно достигли нашей цели!
вы можете проверить исходный код здесь, на Github.
Спасибо за прочтение!