Marko — это современный фреймворк для разработки интерфейсов на JavaScript, ориентированный на высокую производительность и удобство работы с компонентами. Компонентная архитектура в Marko позволяет создавать повторно используемые, изолированные блоки интерфейса с чётко определённой логикой и состоянием.
Компонент в Marko состоит из трёх основных частей:
.marko файл, в
котором описывается разметка компонента с использованием синтаксиса
Marko. Шаблон поддерживает динамическое связывание данных и рендеринг
вложенных компонентов.<style> внутри
.marko файла или подключены отдельным файлом.Пример базового компонента:
<template>
<div class="counter">
<h1>${state.count}</h1>
<button on-click('increment')>Увеличить</button>
</div>
</template>
<script>
class {
state = { count: 0 };
increment() {
this.state.count += 1;
}
}
</script>
<style>
.counter {
text-align: center;
font-family: Arial, sans-serif;
}
button {
padding: 0.5em 1em;
margin-top: 10px;
}
</style>
Marko использует реактивное состояние через объект
state. Любое изменение свойства state
автоматически вызывает обновление интерфейса. Это позволяет легко
создавать интерактивные компоненты без необходимости вручную управлять
DOM.
Ключевые особенности:
state.<MyComponent count=5 />
В дочернем компоненте:
<h1>${input.count}</h1>
Marko предоставляет методы жизненного цикла, позволяющие управлять состоянием и поведением компонентов на разных этапах:
onCreate() — вызывается при создании компонента, до
монтирования в DOM.onMount() — вызывается после монтирования компонента в
DOM.onUpdate() — вызывается после обновления состояния
компонента.onDestroy() — вызывается перед удалением компонента из
DOM.Пример использования методов жизненного цикла:
class {
onCreate() {
this.state.count = 0;
}
onMount() {
console.log('Компонент смонтирован');
}
onUpdate() {
console.log('Состояние обновлено', this.state.count);
}
onDestroy() {
console.log('Компонент удаляется');
}
}
Компоненты Marko могут быть вложены друг в друга, что позволяет
строить сложные интерфейсы из простых повторно используемых блоков. Для
этого используется синтаксис <ИмяКомпонента />.
Пример:
<template>
<Card title="Заголовок">
<p>Содержимое карточки</p>
</Card>
</template>
Внутри Card.marko можно использовать слот для передачи
контента:
<div class="card">
<h2>${input.title}</h2>
<div class="content">
<slot />
</div>
</div>
Для связи дочернего компонента с родительским используется механизм
событий. Дочерний компонент может вызвать событие, которое родитель
слушает через атрибут on-*.
Пример:
<!-- Родительский компонент -->
<ChildComponent on-increment('handleIncrement') />
<script>
class {
handleIncrement(event) {
console.log('Дочерний компонент увеличил счетчик', event.detail);
}
}
</script>
В дочернем компоненте:
this.emit('increment', { value: this.state.count });
Marko поддерживает частичный рендер и обновление только изменившихся частей компонента. Это достигается за счёт виртуального DOM и реактивной модели состояния. Использование локального состояния и изоляции компонентов минимизирует избыточные перерисовки, что критично для высокопроизводительных приложений.
В проекте на Marko компоненты обычно организуются по следующему принципу:
src/
components/
Header/
index.marko
style.css
Footer/
index.marko
style.css
Button/
index.marko
style.css
pages/
Home.marko
About.marko
Каждый компонент изолирован, что облегчает поддержку и масштабирование приложения, а также позволяет легко повторно использовать блоки интерфейса в разных частях проекта.
Комплексное понимание компонентной архитектуры в Marko обеспечивает основу для построения крупных, интерактивных веб-приложений с чистой, управляемой структурой и высокой производительностью.