Темы



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>

7c959b278ee2445efb8642c6d368e721.gif

На данном этапе, сетка уже должна иметь 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>

© Habrahabr.ru