Mithril предоставляет встроенный механизм работы с событиями через
объект vnode.attrs и специальные атрибуты
при создании виртуальных DOM-узлов с помощью функции m().
Любой HTML-элемент, созданный через m(), может принимать
стандартные события, такие как onclick,
oninput, onchange и другие.
m("button", { onclick: () => console.log("Нажата кнопка") }, "Нажми меня")
В этом примере onclick принимает функцию-обработчик.
Важный момент: функция получает объект события Event в
качестве аргумента. Это позволяет использовать стандартные свойства
события, такие как event.target или
event.preventDefault().
m("input", {
oninput: (e) => console.log(e.target.value)
})
Иногда требуется передать дополнительные данные в обработчик события. В Mithril для этого используется замыкание:
const handleClick = (id) => () => console.log(`Элемент с id ${id} нажат`);
m("button", { onclick: handleClick(42) }, "Нажми меня")
Такой подход гарантирует, что правильный контекст и параметры будут доступны при срабатывании события.
Dелегирование событий — это метод оптимизации, при котором один
обработчик закрепляется на родительском элементе и управляет событиями
для всех дочерних элементов, удовлетворяющих определённым условиям. В
Mithril делегирование можно реализовать через проверку
event.target или использование dataset для
идентификации элементов.
m("ul", {
onclick: (e) => {
if (e.target.tagName === "LI") {
console.log(`Нажат элемент: ${e.target.dataset.id}`);
}
}
}, [
m("li", { "data-id": 1 }, "Элемент 1"),
m("li", { "data-id": 2 }, "Элемент 2")
])
Такой подход уменьшает количество отдельных обработчиков и улучшает производительность при большом количестве динамических элементов.
При работе с формами часто необходимо предотвратить стандартное
поведение браузера (например, отправку формы). В Mithril это делается
через вызов event.preventDefault() внутри обработчика:
m("form", {
onsubmit: (e) => {
e.preventDefault();
console.log("Форма обработана без перезагрузки страницы");
}
}, [
m("input", { type: "text", name: "name" }),
m("button", { type: "submit" }, "Отправить")
])
this и
стрелочные функцииПри использовании обработчиков важно помнить о контексте
this. В стандартных функциях this зависит от
вызова, в стрелочных функциях оно лексическое. В Mithril чаще всего
используют стрелочные функции, чтобы избежать потери контекста:
const component = {
view: () => m("button", {
onclick: () => console.log(this) // 'this' ссылается на внешнюю область, а не на компонент
}, "Клик")
}
Для доступа к самому компоненту лучше использовать
vnode.state или замыкания:
const component = {
oninit: (vnode) => {
vnode.state.count = 0;
},
view: (vnode) => m("button", {
onclick: () => {
vnode.state.count++;
console.log(vnode.state.count);
}
}, "Клик")
}
Mithril поддерживает динамическое обновление атрибутов. Обработчики могут изменяться вместе с состоянием компонента:
const component = {
count: 0,
view: (vnode) => m("button", {
onclick: () => {
vnode.state.count++;
console.log(vnode.state.count);
}
}, `Нажато ${vnode.state.count} раз`)
}
При перерендеринге старые обработчики автоматически заменяются на новые, что упрощает управление состоянием и предотвращает утечки памяти.
Для взаимодействия с клавиатурой и мышью используются стандартные события:
onkeydown, onkeyup,
onkeypressonmousedown, onmouseup,
onmousemove, onmouseenter,
onmouseleaveПример обработки нажатия клавиши Enter:
m("input", {
onkeydown: (e) => {
if (e.key === "Enter") console.log("Нажата клавиша Enter");
}
})
Использование делегирования вместе с механизмом виртуального DOM в Mithril позволяет добиться высокой производительности даже при больших и сложных интерфейсах.
vnode.attrs.vnode.state
для сохранения контекста компонента.event.preventDefault() для контроля поведения
браузера.Этот подход к событиям делает интерфейсы гибкими, оптимизированными и легко поддерживаемыми.