Новый фронтенд-фреймворк?

от автора

Или чистый 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, чтобы обновить компонент после вызова обработчика события, что эквивалентно предыдущему примеру.

Жизненный цикл

Последний аспект, который нам нужно понять перед тем, как приступить к разработке реальных приложений, — это жизненный цикл компонента.

Он состоит всего из четырех этапов:

  1. Создать компонент

  2. Присоединить к DOM

  3. Обновить DOM

  4. Отсоединить от 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *