Как получить vue-draggable для работы с несколькими вложенными компонентами?

Я строю сайт-конструктор, используя vue.js. У меня есть эти компоненты:

  • Раздел
  • Ряд
  • Компонент (например, текст / IMG / и т. Д.)

Одна страница будет иметь несколько разделов, один раздел будет иметь несколько строк, а одна строка будет иметь несколько компонентов.

Это означает, что у меня есть такая структура:

  • VueDraggable
    • Разделы
      • Vue Draggable
        • Ряды
          • Vue Draggable
            • Компоненты

Теперь - vue draggable хорошо работает для перетаскивания разделов и компонентов, однако, это не совсем хорошо для перетаскивания моих строк. Когда я беру строку и освобождаю ее в другой позиции, vue-draggable вызывает событие @change, однако положение моих строк не меняется.

Вот как выглядит код:

Builder.vue

<template>
  <div class="w-100">
    <draggable 
      class="list-group w-100 h-100 align-items-center"
      :list="sections"
      group="sections">
        <editor-section-saffron
          v-for="section in sections"
          :key="section.id"
          :section-id="section.id"
          :section-name="section.id.toString()" 
          :default-layout="section.defaultLayout">
        </editor-section-saffron>
    </draggable>
  </div>
</template>
<script>
import draggable from 'vuedraggable'
import EditorSectionSaffron from './EditorSectionSaffron'
export default {
  data() {
    return {
      sections: [
        { id: 1 },
        { id: 2 }
      ]
    }
  },
  components: {
    draggable, EditorSectionSaffron
  }
}
</script>

EditorSectionSaffron.vue (я упростил код, заменив компонент строки простым div. Результат тот же)

<template lang="pug">
  collapsible-card-lasagne.section--wrapper.my-3.w-100(
    header-background="bg-primary"
    header-text-color="text-white"
    :display-chevron="false"
  )
    template(slot="header-left")
      .section-header--left.font-weight-bold
        font-awesome-icon.mr-3(icon="arrows-alt" @click.stop="")
        span {{ sectionName }}
    template(slot="header-right")
      .section-header--left
        font-awesome-icon.mx-2(icon="copy" @click.stop="onDuplicate")
        font-awesome-icon.mx-2(icon="trash" @click.stop="onDelete")
    .section-body
      draggable.list-group.w-100.h-100.align-items-center(
        :list="rows"
        :group="`section-${sectionId}-rows`"
      )
        .bg-red.w-100.my-2(v-for="x in 3") {{ x }}
</template>
<script>
import draggable from 'vuedraggable'

import CollapsibleCardLasagne from '@/dashboard/cards/CollapsibleCardLasagne'
export default {
  name: 'EditorSectionSaffron',
  components: {
    CollapsibleCardLasagne,
    draggable,
  },
  props: {
    sectionId: {
      type: Number,
      required: true
    },
    defaultLayout: {
      type: Object,
      default: null
    },
    sectionName: {
      type: String,
      default: 'Section'
    }
  },
  data() {
    return {
      rows: [
        { index: 0 },
        { index: 1 }
      ]
    }
  },
  methods: {
    onEdit() {

    },
    onDuplicate() {

    },
    onDelete() {

    },
    onDuplicateRow(defaultLayout) {
      this.rows.push({
        index: this.rows[this.rows.length - 1].index + 1,
        defaultLayout
      })
    },
    onEditRow(row) {

    },
    onDeleteRow(row) {
      this.rows = this.rows.filter(r => r.index !== row.index)
    }
  }
}
</script>

Любая идея будет высоко ценится.

0 ответов

Другие вопросы по тегам