Простой Vue.Перетаскиваемый внутри вложенных разрывов списка ul во время рендеринга

#javascript #html #vue.js #vue.draggable

#javascript #HTML #vue.js #vue.перетаскиваемый

Вопрос:

Редактировать

Я попытался создать простую песочницу на основе отзывов @Amaarrockz, и проблема, с которой я сталкиваюсь, все еще возникает:

 <div id="app">
    <ul>
        <li v-for="stepTitle in collections.stepTitles">
            {{ stepTitle.name }}
                <draggable tag="ol" v-model="collections.children">
                    <li v-for="child in collections.children">{{ child.step }}</li>
                </draggable>
        </li>
    </ul>
</div>
 
 Vue.use('draggable');
var collection = {
    "stepTitles": [{
        "name": "Step 1",
        "id": 1
    }, {
        "name": "Step 2",
        "id": 2
    }, {
        "name": "Step 3",
        "id": 3
    }],
    "children": [{
            "parentID": 1,
            "step": "Child 1"
        },
        {
            "parentID": 2,
            "step": "Child 1"
        },
        {
            "parentID": 2,
            "step": "Child 2"
        },
        {
            "parentID": 2,
            "step": "Child 3"
        },
        {
            "parentID": 3,
            "step": "Child 1"
        },
        {
            "parentID": 3,
            "step": "Child 2"
        }
    ]
};
new Vue({
    el: '#app',
    data: {
        collections: collection
    }
});
 

Конечный результат, который я хотел бы, должен быть:

  • Шаг 1 (не перетаскивается)
    1. Дочерний элемент 1 (перетаскиваемый)
  • Шаг 2 (не перетаскивается)
    1. Дочерний элемент 1 (перетаскиваемый)
    2. Дочерний элемент 2 (перетаскиваемый)
    3. Дочерний элемент 3 (перетаскиваемый)
  • Шаг 3 (не перетаскивается)
    1. Дочерний элемент 1 (перетаскиваемый)
    2. Дочерний элемент 2 (перетаскиваемый)

где дочерние элементы должны расширяться только до 1 уровня и быть подвижными внутри своих соответствующих родителей.

Я свел это к тому факту, что, похоже, существует проблема с рендерингом a <draggable> внутри родительского <ul> элемента. Если я создам 2-мерный массив JSON, который использует родительскую v-for переменную, например stepTitle , он выдает ошибку about stepTitle is not defined . Если я создаю одномерный массив JSON и использую разные v-for переменные, он неправильно отображает HTML.

Я повсюду искал примеры с вложенными перетаскиваемыми объектами, но все примеры, которые я нахожу, показывают, что родительский элемент перетаскивается, что не является желаемым результатом. Кроме того, дочерний элемент смог стать родителем, что также не то, что я хочу.

Неправильный рендеринг говорит мне, что я сделал что-то не так, но есть ли у vue-draggable проблемы с рендерингом дочерних <draggable> элементов внутри обычного <ul> ?

Исходное сообщение

У меня есть интересная проблема при использовании vue.draggable, на решение которой я потратил часы.

Общая концепция заключается в том, что у меня есть массив, который содержит вложенный массив. Вот данные:

 "steps": [{
    "name": "Title 1",
    "steps": ["Sub step 1"]
}, {
    "name": "Title 2",
    "steps": ["Sub step 1", "Sub step 2", "Sub step 3"]
}, {
    "name": "Title 3",
    "steps": ["Sub step 1", "Sub step 2"]
}]
 

который должен отображать что-то вроде этого:
Правильный рендеринг

Цель состоит в том, чтобы сделать эти подэтапы перетаскиваемыми и соответствующим образом настроить массив Vue. Однако, когда я ввел <draggable> тег, код прерывается с помощью:

Свойство или метод «item» не определены в экземпляре, но на них ссылаются во время рендеринга.

Вот полный код для контекста:

HTML

 <ul class="steps-section-added">
    <li class="list-group" v-for="(item, index) in stepSections" :key="item.stepSectionTitle" v-on:remove="removeAddedStepSection(index)">
        <div class="row">
            <div class="col-12">
                <div class="ist-group-item list-group-item-steps-header" style="display: table;width: 100%;">{{ item.stepSectionName }}
                    <span>
                        <button class="btn btn-outline-success-white float-right d-flex justify-content-center align-content-between ml-2" v-on:click="removeAddedStepSection(index)"><span class="material-icons">delete</span></button>
                        <button class="btn btn-outline-success-white float-right d-flex justify-content-center align-content-between" v-on:click="editAddedStepSection(index)"><span class="material-icons">edit</span></button>
                    </span>
                </div>
                <div>
                    <!-- Code breaks somewhere here-->
                    <draggable v-model="item.steps" tag="ol" @start="drag=true" @end="drag=false" style="padding-left: 0px;">
                        <li class="recipe-list-group-item list-group-item list-group-item-steps-body" v-for="t in item.steps">{{ t.stepText }}</li>
                    </draggable>
                </div>
            </div>
        </div>
    </li>
</ul>
 

Приложение Vue

 Vue.use('draggable');
var stepsVM = new Vue({
    el: '#step-section-ingredients',
    data: {
        steps: [],
        stepSections: [],
        stepSectionTitle: '',
        drag: false
    },
    methods: {
        addNewStep: function () {
            //
        },
        removeTextRow: function (index) {
            //
        },
        addNewStepSection: function () {
            //
        },
        removeAddedStepSection: function (index) {
            //
        },
        editAddedStepSection: function (index) {
            //
        }
    }
});
 

Если я заменю <draggable> тег на an <ol> , он отобразится правильно, но вложенные компоненты не будут перетаскиваться. Как только я ввожу перетаскиваемый тег, он прерывается. После нескольких часов экспериментов я думаю, что ошибка относится к v-for="t in item.steps"> . Если это так, как мне заставить item.steps его работать?

Любые рекомендации будут оценены 🙂

Комментарии:

1. Если вы хотите, чтобы вспомогательные элементы можно было перетаскивать, вам нужно изменить структуру данных

2. Даже если я изменяю данные в "substeps": [{id: 0, stepText: "Sub step 1"}] коде, все равно кажется, что он терпит неудачу. Есть ли у вас рекомендации относительно того, какая структура данных была бы лучше? Я все еще немного застрял

3. нет, этого изменения недостаточно

4. @Amaarrockz Я думаю, что я все еще немного в замешательстве, нужно ли мне создавать совершенно новую структуру?

Ответ №1:

Да, ваша структура должна быть примерно такой

 "steps": [{
    "name": "Step 1",
     id: 1,
     parentId: null
}, {
    "name": "Sub Step 1",
     id: 11,
     parentId: 1
}, {
    "name": "Sub Step 2",
     id: 12,
     parentId: 1
}, {
    "name": "Step 2",
     id: 2,
     parentId: null
}]
 

Это одномерный массив, но он может расширяться до n уровней. Если бы вы могли поддерживать подобную структуру, то, используя vue-draggable, вы «переходите» с шага 1 на шаг 2, основываясь на сдвиге, вам просто нужно обновить родительский идентификатор