GridStack + Vue 3 composition api
Далее, нам надо определиться со способом, которым мы будем загружать данные для отображения на сетке. Их всего два: js или html.
Допустим у вас есть некий массив blocks, в котором лежат объекты с полями, необходимыми для установки размера и позиции элемента.
const blocks = [
{
w: 2,
h: 2,
x: 0,
y: 0,
id: 'Unic1',
type: 'Standart',
},
{
w: 2,
h: 2,
x: 0,
y: 0,
id: 'Unic2',
type: 'Image',
},
{
w: 2,
h: 2,
x: 0,
y: 0,
id: 'Unic3',
type: 'Text',
},
]
Поле type нам может понадобиться в том случае, если добавляемые блоки отличны друг от друга (например: разные компоненты).
Первый способ. Отобразим данный массив при помощи js.
<script setup lang="ts">
import { onMounted } from 'vue';
import { GridStack } from 'gridstack';
import 'gridstack/dist/gridstack.min.css';
const blocks = [
{
w: 2,
h: 2,
x: 0,
y: 0,
id: 'Unic1',
type: 'Standart',
},
{
w: 2,
h: 2,
x: 0,
y: 0,
id: 'Unic2',
type: 'Image',
},
{
w: 2,
h: 2,
x: 0,
y: 0,
id: 'Unic3',
type: 'Text',
},
]
// Тут будут лежать минимальные настройки для GridStack
const gridStackOptions = {
animate: true,
cellHeight: '180px',
float: true,
column: 12,
margin: 4,
resizable: {
handles: 'e, se, s, sw, w, nw, n, ne',
},
}
// Так как данная библиотека рабоатет с уже имеющимся HTML, выполняем всё в onMounted
onMounted(() => {
const grid = GridStack.init(gridStackOptions, 'grid-stack')
// Загружаем данные в сетку
blocks.map((block) => {
grid.addWidget({
x: block.x,
y: block.y,
w: block.w,
h: block.h,
id: block.id,
})
})
})
</script>

На данном этапе, сетка уже должна иметь 3 элемента, которые вы можете свободно перемещать и изменять их размер. Минус такого подхода в том, что при добавлении не просто блока, а некоего компонента, начинаются танцы с бубнами, где рискуешь потерять реактивность, так как в этом случае, можно передавать содержимое widget’а только в виде html.
Второй способ (которым я и воспользовался), больше подходит под большинство задач, так как автор данной библиотеки, пользуется фрэймворком Angular, из‑за чего в фундамент заложено декларативное встраивание контента.
<script setup lang="ts">
import { onMounted } from 'vue';
import { GridStack } from 'gridstack';
import 'gridstack/dist/gridstack.min.css';
import Standart from '../standart/index.vue';
import LineChart from '../text/index.vue';
const blocks = [
{
w: 2,
h: 2,
x: 0,
y: 0,
id: 'Unic1',
type: 'standart',
},
{
w: 2,
h: 2,
x: 0,
y: 0,
id: 'Unic2',
type: 'image',
},
{
w: 2,
h: 2,
x: 0,
y: 0,
id: 'Unic3',
type: 'text',
},
]
// Тут будут лежать минимальные настройки для GridStack
const gridStackOptions = {
animate: true,
cellHeight: '180px',
float: true,
column: 12,
margin: 4,
resizable: {
handles: 'e, se, s, sw, w, nw, n, ne',
},
}
// Так как данная библиотека рабоатет с уже имеющимся HTML, выполняем всё в onMounted
onMounted(() => {
GridStack.init(gridStackOptions, 'grid-stack')
})
</script>
