Или чистый JavaScript с двумя вспомогательными функциями?
В этой статье я расскажу о том, как разрабатывать веб-компоненты с использованием библиотеки Fusor и преимуществах данного подхода.
Такие компоненты можно будет затем собирать в полноценные веб-приложения, сопоставимые с теми, что созданы с использованием React, Angular, Vue, Solid, Svelte и т.д.
АПИ Fusor состоит всего из двух основных функций:
-
Создать DOM-элемент, обернутый в специальный объект.
-
Обновить DOM-элемент, обернутый в специальный объект.
Плюс еще несколько редко используемых функций, таких как:
-
Получить DOM-элемент из специального объекта.
Вам не обязательно что-либо знать об этом специальном объекте.
Создание DOM-элемента
Создание через JSX
import { getElement } from "@fusorjs/dom"; const count = 0; // Создание через JSX const message = <div>Seconds {count} elapsed</div>; document.body.append(getElement(message)); // Получить
Мы использовали функции АПИ создать и получить.
Альтернативное создание без JSX
import { div } from "@fusorjs/dom/html"; const message = div("Seconds ", count, " elapsed"); // Создать
Обновление элемента DOM
import { getElement, update } from "@fusorjs/dom"; let count = 0; const message = <div>Seconds {() => count} elapsed</div>; // Создать document.body.append(getElement(message)); // Получить setInterval(() => { count += 1; update(message); // Обновить }, 1000);
Мы использовали функцию АПИ обновить. Она обновляет элемент DOM и все его дочерние элементы рекурсивно. Она получает новые значения из вызовов функций, делая их динамическими.
Дочерние элементы, атрибуты и свойства могут быть динамическими.
<div class={() => (toggle ? "on" : "off")} />
Обновления DOM будут происходить только в том случае, если новые значения отличаются от текущих.
Установка параметров
В основном устанавка параметров происходит как обычно:
<div style="padding:1em" />
Однако иногда вам потребуется различать атрибуты и свойства. Чтобы указать их тип, вы можете добавить суффиксы _a
или _p
к их названиям:
<div name1_a="attribute" name2_p="property" />
Чтобы добавить обработчик события, вы всегда должны использовать суффикс _e
:
<div click_e={() => "event handler"} />
Есть и дополнительные типы, и некоторые могут принимать опции для обеспечения полной совместимости со стандартами W3C:
<div click_e_capture_once={() => "event handler"} />
Создание компонента
Создавайте свои компоненты, используя специальные объекты Fusor. Инкапсулируйте состояние и параметры внутри функций. Используйте заглавные буквы для имен ваших компонентов.
Вот пример компонента кнопки счётчика:
import { getElement, update } from "@fusorjs/dom"; const CountingButton = (props) => { let count = props.count ?? 0; // Состояние const self = ( <button click_e={() => { count += 1; update(self); }} > Clicked {() => count} times </button> ); return self; }; const App = () => ( <div style="padding:1em"> <p>Three counting buttons</p> <CountingButton /> <CountingButton count={22} /> <CountingButton count={333} /> </div> ); document.body.append(getElement(App()));
Компонент CountingButton
обновляет только малую часть своего DOM-элемента, не затрагивая остального приложения.
Когда вы разберетесь, как работает этот компонент, то посмотрите как можно переписать его немного короче, с тем же результом:
const CountingButton = ({ count = 0 }) => ( <button click_e={(event, self) => { count += 1; update(self); }} > Clicked {() => count} times </button> );
Каждая функция обработчика событий получает два аргумента: стандартный объект события и текущий специальный объект.
Теперь, если вы разобрались и с этим примером, посмотрите и на кратчайшую версию того же компонента:
const CountingButton = ({ count = 0 }) => ( <button click_e_update={() => (count += 1)}> Clicked {() => count} times </button> );
Мы добавили опцию update
, чтобы обновить компонент после вызова обработчика события, что эквивалентно предыдущему примеру.
Жизненный цикл
Последний аспект, который нам нужно понять перед тем, как приступить к разработке реальных приложений, — это жизненный цикл компонента.
Он состоит всего из четырех этапов:
-
Создать компонент
-
Присоединить к DOM
-
Обновить DOM
-
Отсоединить от DOM
import { getElement, update } from "@fusorjs/dom"; const IntervalCounter = ({ count = 0 }) => { console.log("1. Создать компонент"); return ( <div mount={(self) => { console.log("2. Присоединить к DOM"); const timerId = setInterval(() => { count++; update(self); console.log("3. Обновить DOM"); }, 1000); return () => { clearInterval(timerId); console.log("4. Отсоединить от DOM"); }; }} > Since mounted {() => count} seconds elapsed </div> ); }; const instance = <IntervalCounter />; const element = getElement(instance); document.body.append(element); setTimeout(() => element.remove(), 15000);
Свойство mount
содержит функцию, которая выполняется, когда компонент добавляется в DOM. Эта функция принимает один аргумент: текущий специальный объект. Она также может вернуть другую функцию, которая выполняется, когда компонент удаляется из DOM.
Мы полностью контролируем эти четыре этапа жизненного цикла. Это позволяет нам создавать, обновлять и сравнивать компоненты, используя кастомные асинхронные или параллельные стратегии для разных компонентов, с учетом кадров анимации.
Это конец туториала
Как вы могли заметить из этого туториала, Fusor прост, лаконичен и ясен. Чаще всего вам будет достаточно использовать только две функции АПИ. Тем не менее, он также предлагает множество возможностей для кастомизации и гибкости, когда это необходимо.
Итак, чтобы ответить на вопрос в заголовке, Fusor — это маленькая библиотека JavaScript, а не фреймворк, но с помощью нее можно достичь тех же результатов, что и с фреймворками.
С чего начать
Все примеры выше доступны на CodeSandbox.
Также ознакомьтесь с примером SVG аналоговых часов.
Вот пример реального приложения.
Стартовые шаблоны проектов:
Спасибо
ссылка на оригинал статьи https://habr.com/ru/articles/837938/
Добавить комментарий