Фреймворк Mithril.js предоставляет легковесный, но мощный подход к работе с динамическими интерфейсами, включая формы. Формы в Mithril можно строить как простые элементы HTML, но с использованием реактивных данных, компонентов и удобных методов управления состоянием.
Форма в Mithril строится с использованием функции m(),
которая создаёт виртуальные узлы. Базовая структура формы выглядит
следующим образом:
const FormComponent = {
view: () =>
m("form", { onsubmit: (e) => e.preventDefault() },
m("label", "Имя: "),
m("input[type=text]", { placeholder: "Введите имя" }),
m("button[type=submit]", "Отправить")
)
};
Ключевые моменты:
onsubmit обязательно обрабатывается через
preventDefault(), чтобы предотвратить стандартное поведение
браузера.m(),
что позволяет интегрировать их с реактивной моделью данных.Mithril не предоставляет встроенного state management, но реактивные данные можно хранить в простых объектах. Например, связывание поля ввода с данными выглядит так:
const formData = { name: "" };
const FormComponent = {
view: () =>
m("form", {
onsubmit: (e) => {
e.preventDefault();
console.log(formData.name);
}
},
m("label", "Имя: "),
m("input[type=text]", {
value: formData.name,
oninput: (e) => formData.name = e.target.value
}),
m("button[type=submit]", "Отправить")
)
};
Особенности:
value задаёт текущее значение поля.oninput обновляет объект formData,
обеспечивая синхронизацию данных с интерфейсом.Для сложных форм рекомендуется разбивать форму на подкомпоненты, каждый из которых отвечает за отдельный набор полей. Это повышает читаемость кода и облегчает повторное использование.
Пример разделения формы на блоки:
const PersonalInfo = {
view: ({ attrs }) =>
m("fieldset",
m("legend", "Личная информация"),
m("label", "Имя: "),
m("input[type=text]", {
value: attrs.data.name,
oninput: (e) => attrs.data.name = e.target.value
}),
m("label", "Возраст: "),
m("input[type=number]", {
value: attrs.data.age,
oninput: (e) => attrs.data.age = e.target.value
})
)
};
const ContactInfo = {
view: ({ attrs }) =>
m("fieldset",
m("legend", "Контакты"),
m("label", "Email: "),
m("input[type=email]", {
value: attrs.data.email,
oninput: (e) => attrs.data.email = e.target.value
}),
m("label", "Телефон: "),
m("input[type=tel]", {
value: attrs.data.phone,
oninput: (e) => attrs.data.phone = e.target.value
})
)
};
const FormComponent = {
data: { name: "", age: "", email: "", phone: "" },
view: function() {
return m("form", {
onsubmit: (e) => e.preventDefault()
},
m(PersonalInfo, { data: this.data }),
m(ContactInfo, { data: this.data }),
m("button[type=submit]", "Отправить")
);
}
};
Преимущества такого подхода:
Для валидации данных можно использовать функции, которые проверяют значения полей перед отправкой формы:
const validate = (data) => {
const errors = {};
if (!data.name) errors.name = "Имя обязательно";
if (!data.email.includes("@")) errors.email = "Некорректный email";
return errors;
};
const FormComponent = {
data: { name: "", email: "" },
errors: {},
view: function() {
return m("form", {
onsubmit: (e) => {
e.preventDefault();
this.errors = validate(this.data);
if (Object.keys(this.errors).length === 0) {
console.log("Форма валидна", this.data);
}
}
},
m("label", "Имя: "),
m("input[type=text]", {
value: this.data.name,
oninput: (e) => this.data.name = e.target.value
}),
this.errors.name && m("div.error", this.errors.name),
m("label", "Email: "),
m("input[type=email]", {
value: this.data.email,
oninput: (e) => this.data.email = e.target.value
}),
this.errors.email && m("div.error", this.errors.email),
m("button[type=submit]", "Отправить")
);
}
};
Особенности валидации:
errors.Mithril поддерживает динамическое создание полей с использованием массивов данных:
const FormComponent = {
data: { phones: [""] },
view: function() {
return m("form", {
onsubmit: (e) => e.preventDefault()
},
m("h3", "Телефоны"),
this.data.phones.map((phone, index) =>
m("input[type=tel]", {
value: phone,
oninput: (e) => this.data.phones[index] = e.target.value
})
),
m("button[type=button]", {
onclick: () => this.data.phones.push("")
}, "Добавить телефон"),
m("button[type=submit]", "Отправить")
);
}
};
Преимущества такого подхода:
Mithril легко интегрируется с сторонними библиотеками для валидации
или масок ввода, так как все элементы формы рендерятся стандартными
HTML-тегами. Например, можно подключить библиотеку для форматирования
номеров телефонов через oninput или использовать валидацию
через onblur.
Mithril обеспечивает эффективное обновление DOM, поэтому каждая
реакция на oninput не приводит к полной перерисовке формы.
Чтобы дополнительно оптимизировать производительность:
key при рендеринге списков динамических
полей.view, вынося их в
отдельные функции.Фреймворк Mithril позволяет строить гибкие и масштабируемые формы с контролем состояния, валидацией и динамическими полями, сохраняя при этом лёгкость и простоту структуры кода.