Рубрики
Без рубрики

Директива Vue – нажмите на улицу

Проблема, которую я хочу решить: мне нужно поймать моменты, когда я нажимаю за пределы какого -либо элемента … Tagged with Vue, JavaScript.

Проблема, которую я хочу решить, заключается в:

Мне нужно поймать моменты, когда я нажимаю за пределы какого -то элемента

Почему?

Это может быть полезно для компонентов пользовательского интерфейса, таких как выпадающие, дату, модальные окна – чтобы назначить некоторую логику для этого определенного поведения

Как стартер, я скажу, что принятое значение для директивы будет просто функцией, и в коде это будет выглядеть:


В конце текста будет раздел «Рефакторинг» с расширением логики для большего использования способами использования

Ссылки используются

  1. Буфи
  2. Vuetify

Текст и код в статье являются результатом анализа с открытым исходным кодом и прохождения существующих решений, написанных выше

Решение

Я собираюсь использовать Vue в качестве структуры пользовательского интерфейса здесь. Почему? Я просто использую Vue в качестве своей нынешней бизнес -рамки, так что для меня это был бы хороший шанс погрузиться в него глубже.

Прежде всего, давайте просто определим функцию, которая ловит внешние клики, без каких-либо обертка, почти псевдокод

Определите, когда мы можем сказать, что мы щелкнули вне элемента

Для этого нам нужно знать, где мы щелкнули, и какова наш элемент с назначенным слушателем, поэтому функция начнется так:

function onClickOutside(event, el) {
  const isClickOutside =
    event.target !== el
    && !el.contains(event.target);
}

Теперь, если флаг правда, нам нужно вызвать какого -то обработчика:

function onClickOutside(event, el, handler) {
  const isClickOutside =
    event.target !== el
    && !el.contains(event.target);

  return isClickOutside ? handler(event, el) : null;
}

Для меня это выглядит немного тяжело только, что я должен следовать заказу аргументов, поэтому вместо этого я буду использовать один параметр объекта; Функция Onclickoutside ({Event, El, Handler})

Начните слушать функцию

Логически, нам нужно найти место, где мы можем использовать это:

document.addEventListener(
  'click',
  (event) => onClickOutside({ event })
)

Здесь – без изобретения, просто собираюсь вветь док и увидеть о Пользовательские директивы

По сути, нам нужно всего три стадии жизненного цикла:

  1. привязать – назначить директивную логику элементу и создать слушателей
  2. разгибай – когда элемент больше нет в доме И нам нужно удалить наших слушателей

Чтобы иметь возможность поймать слушателей, приписывающих элементу, я создам их карту – для хранения и быстрого достижения их:

const map ();

Прежде чем написать свои крючки, я напишу функцию для повторного использования кода – вот я буду манипулировать своим событием:

function toggleEventListeners(action, eventHandler) {
  document[`${action}EventListener`]('click', eventHandler, true);
}

(«Истинный» третий парамет, который я использовал для вызова обработчика на фазе захвата, чуть раньше, чем при пузырчах)

Функция связывания будет выглядеть как:

function bind(el, { value: handler }) {
  const eventHandler = event => onClickOutside({ el, event, handler});

  toggleEventListeners('add', eventHandler);

  instances.set(
    el,
    eventHandler
  );
}

Function Function сделает простую логику для удаления наших слушателей из системы:

function unbind(el) {
  const eventHandler = instances.get(el);

  toggleEventListeners('remove', eventHandler);

  instances.delete(el);
}

В конце нам просто нужно правильно экспортировать эту директиву и связаться с нашим экземпляром Vue в файле ‘main.js:

const directive = {
  bind,
  unbind,
};

export default directive;

‘main.js’:

import Vue from 'vue'
import App from './App.vue'

import clickOutside from './directives/clickOutside';

Vue.config.productionTip = false

Vue.directive('click-outside', clickOutside);

new Vue({
  render: h => h(App),
}).$mount('#app')

Вот и все как минимум, теперь идет следующий раздел

Рефакторинг

Я хотел бы справиться не только как значение как значение, но и объект

//Validator function
function processArgs(value) {
  const isFunction = typeof value === 'function';

  if (!isFunction && typeof value !== 'object') {
      throw new Error(`v-click-outside: Binding value should be a function or an object, ${typeof bindingValue} given`)
  }

  return {
    handler: isFunction ? value : value.handler,
  }
}

//Handler goes from the processing function
function bind(el, { value }) {
  const { handler } = processArgs(value);

  //...function body
}

Я хочу добавить функцию промежуточного программного обеспечения для определения условий, когда я хочу или не хочу вызывать свой обработчик

Расширить результат обработки с помощью метода промежуточного программного обеспечения

return {
  handler: isFunction ? value : value.handler,
  middleware: value.middleware || (() => true),
};

Расширить логику функции ClickOutside

function onClickOutside({ event, el, handler, middleware }) {
  const isClickOutside =
    event.target !== el
    && !el.contains(event.target);

  if (!isClickOutside || !middleware(event, el)) {
    return null;
  }

  return handler(event, el);
}

Тогда везде, где бы вы ни использовали обработчик, не забудьте также также разрушить промежуточное программное обеспечение и добавить в качестве параметров для привязки и адаптера функции

Ну, вот и все, полный пример можно найти здесь, в моих Gists – https://gist.github.com/disgusting-dev/8d45aebff8a536af1cba39b0fcd203e3
Спасибо за чтение, дальше будет все больше и больше, поэтому не стесняйтесь подписаться, чтобы не пропустить никакого анализа!

Оригинал: “https://dev.to/disgustingdev/vue-directive-click-outside-37nc”