Как стать автором
Обновить

Сигналы, роутинг, реактивность, Fusor приложение

Время на прочтение2 мин
Количество просмотров216

В этом посте я опишу, как настроить современную маршрутизацию и использовать сигналы для реактивного отключения выбранных ссылок.

Сигналы — это просто реализация паттерна "observable". Хотя мы могли бы использовать любую библиотеку для этой цели, мы создадим свою собственную, чтобы обеспечить лучшую наглядность и понимание.

export class Observable {
  #callbacks = new Set();
  notify() {
    for (const fn of this.#callbacks) fn();
  }
  subscribe(callback) {
    this.#callbacks.add(callback);
    return () => this.#callbacks.delete(callback); // unsubscribe
  }
}

Далее нам нужно будет создать библиотеку маршрутизации для нашего приложения. Реализация маршрутизации в современных браузерах проста и не требует использования сторонних библиотек.

import { update } from "@fusorjs/dom";
import { Observable } from "./observable";

const observable = new Observable();
let route = location.hash;

window.addEventListener(
  "popstate",
  () => {
    route = location.hash;
    observable.notify();
  },
  false
);

export const getRoute = () => route;
export const mountRoute = (self) => observable.subscribe(() => update(self));

Далее нам нужен реактивный компонент ссылки, который изменяет свой DOM-узел с элемента a на обычный текст, если текущий маршрут совпадает с его собственным маршрутом.

import { span, a } from "@fusorjs/dom/html";
import { mountRoute, getRoute } from "./route";

const RouteLink = (title, route) =>
  span(
    { mount: mountRoute }, // enable reactivity
    ((cache = a({ href: route }, title)) => () =>
      getRoute() === route ? title : cache)()
  );

Обратите внимание, что в Fusor существует три способа определить HTML-элемент. В приведённом выше примере используются функции span и a. Второй способ включает использование JSX.

<span mount={mountRoute}>{(
  (cache = <a href={route}>{title}</a>) => 
  () => getRoute() === route ? title : cache
)()}</span>

И третий использует функцию h("span", {mount: mountRoute}, .....

Свойство mount позволяет назначить функцию, которая срабатывает, когда элемент присоединяется к DOM. Обратитесь к разделу "Жизненный цикл компонентов" в туториале для получения более подробной информации.

Наконец, мы используем наш компонент для динамического создания списка ссылок и их прикрепления к DOM.

import { getElement } from "@fusorjs/dom";
import { ul, li } from "@fusorjs/dom/html";
import { RouteLink } from "./route-link";

const block = ul(
  [...Array(10)].map((_, i) =>
    li(RouteLink(`${i}. Section`, `#url-to-${i}-section`))
  )
);

document.body.append(getElement(block));

Посмотрите пожалуйста полный рабочий пример.

Репозиторий Fusor.

Спасибо!

Теги:
Хабы:
0
Комментарии0

Публикации

Работа

Ближайшие события