Skip to content

Компонент MasonryGrid ​

Рендерит одну измеряемую обёртку <div> на каждую карточку вокруг слота #item этой карточки — содержимое карточки остаётся полностью вашим, это только измеряет и расставляет обёртку. При включённом options.virtualize обёртку/слот реально получают только карточки, видимые прямо сейчас (± overscan) — смотрите Виртуализацию.

vue
<MasonryGrid :items="items" :options="{ columns: 'auto', minLaneSize: 240 }">
  <template #item="{ item }">
    <MyCard :data="item" />
  </template>
</MasonryGrid>

Пропсы ​

items ​

MasonryGridItem[] · обязателен

Та же форма, что и у MasonryItemDescriptor ядра (смотрите Элементы и бенто-спаны), без el — компонент сам создаёт и владеет обёрткой каждой карточки. Все поля опциональны, включая id: id, colSpan, rowSpan, aspectRatio, estimatedSize, order.

Если id не задан, компонент сам генерирует стабильный id по ссылке на сам объект карточки (WeakMap) — тот же объект в массиве получает тот же id на любом ре-рендере. Если же элементы items каждый раз пересобираются в новые объекты (например, .map() над исходными данными на каждый рендер), у каждого такого объекта будет новый сгенерированный id — тогда лучше задать id явно из собственных данных.

options ​

MasonryOptions · по умолчанию: {}

Передаётся напрямую в createMasonryEngine() — смотрите API движка. У ядра нет живого updateOptions(), поэтому изменение содержимого options (сравнивается структурно через optionsEqual, а не только по ссылке) пересоздаёт движок — инлайн-объект-литерал с идентичным содержимым на каждый рендер этого не вызывает.

sortable ​

boolean · по умолчанию: false

Превращает каждую обёртку карточки в клавиатурно-пересортируемую — смотрите «Сортировка» ниже.

События ​

layout ​

Payload: MasonryItemLayout[]

Срабатывает на каждый пересчёт раскладки движком, с посчитанным прямоугольником каждой карточки.

reorder ​

Payload: MasonryGridItem[]

Срабатывает, когда пользователь пересортировывает карточку с клавиатуры (только при sortable) — смотрите «Сортировка» ниже. Пересортировка никогда не изменяет сами items.

Слоты ​

item ​

Scope: { item: MasonryGridItem }

Единственный слот, рендерится по одному разу на каждую запись в items (или на каждую видимую прямо сейчас запись, при virtualize) — собственное содержимое карточки, обёрнутое в измеряемый <div class="mk-item">, который позиционирует движок.

Сортировка ​

vue
<script setup lang="ts">
import { ref } from 'vue'
import { MasonryGrid } from '@macrulez/masonry-kit-vue'

const items = ref([{ id: 'a' }, { id: 'b' }, { id: 'c' }])
</script>

<template>
  <MasonryGrid :items="items" sortable @reorder="items = $event">
    <template #item="{ item }">
      <MyCard :data="item" />
    </template>
  </MasonryGrid>
</template>

При включённом sortable каждая обёртка карточки становится управляемой с клавиатуры:

  • Пробел или Enter берёт сфокусированную карточку («поднимает» её — вызывает engine.setDragging(id), смотрите API движка, так что пока она активна, исключена из обычной упаковки) либо, если она уже поднята, отпускает её.
  • Стрелки (вниз/вверх при direction: 'vertical', вправо/влево при 'horizontal') двигают поднятую карточку на одну позицию вперёд или назад в items, испуская reorder с новым массивом на каждый шаг.
  • Escape отменяет — восстанавливает items к массиву, зафиксированному в момент поднятия (испуская reorder с этим снимком), и снимает поднятие.

<MasonryGrid> никогда не изменяет items самостоятельно — каждое перемещение это испускание reorder с совершенно новым массивом; именно ваша собственная привязка в духе v-model (@reorder="items = $event") реально его применяет, точно так же, как работает любой другой паттерн управляемого списка.

Каждая обёртка получает role="button", aria-roledescription="Reorderable item", aria-pressed (отражает состояние поднятия) и aria-describedby, указывающий на визуально скрытую строку с инструкцией («Press space or enter to pick up this item…»). Каждое поднятие/перемещение/отпускание/отмена также озвучивается через визуально скрытый регион aria-live="polite".

Указательный/тач-drag намеренно не реализован — смотрите Обзор о том, почему live-перетаскивание мышью не подходит skyline-упаковке так, как дискретный шаг с клавиатуры.