2016-01-19 3 views
3

У меня есть компонент перетаскивания (с помощью Sortable), но я не могу понять логику, чтобы обновить порядок списка после того, как элемент упал в его Новое место.Сброс порядка списка Vue.js всех элементов после перетаскивания

Код (Vue.js):

new Vue({ 
    el: '#app', 
    template: '#dragdrop', 
    data() { 
    return { 
     list: [ 
     {name: 'Item 1', id: 1, order: 0}, 
     {name: 'Item 2', id: 2, order: 1}, 
     {name: 'Item 3', id: 3, order: 2}, 
     {name: 'Item 4', id: 4, order: 3}, 
     {name: 'Item 5', id: 5, order: 4}, 
     {name: 'Item 6', id: 5, order: 5}, 
     ], 
    } 
    }, 
    ready() { 
    Sortable.create(document.getElementById('sort'), { 
     draggable: 'li.sort-item', 
     ghostClass: "sort-ghost", 
     animation: 80, 
     onUpdate: function(evt) { 
     console.log('dropped (Sortable)'); 
     } 
    }); 
    }, 
    methods: { 
    dropped() { 
     console.log('dropped (Vue method)'); 
    } 
    } 
}); 

У меня есть рабочий JSFiddle: https://jsfiddle.net/jackbarham/rubagbc5

Я ищу, чтобы получить order в массиве для синхронизации, так что я могу сделать обновление AJAX как только элемент будет удален.

ответ

4

Это не самое элегантное решение, но я думаю, что он работает. Для этого используется обработчик Sortable onUpdate для обновления базового массива. Всякий раз, когда элемент перетаскивается в новую позицию, он перемещается в одно и то же место в массиве - таким образом модель представления остается в синхронизации с тем, что отображается в представлении. Затем свойства объекта order обновляются, чтобы соответствовать их новым позициям в массиве.

new Vue({ 
    el: '#app', 
    template: '#dragdrop', 
    data() { 
    return { 
     list: [ 
     {name: 'Item 1', id: 1, order: 0}, 
     {name: 'Item 2', id: 2, order: 1}, 
     {name: 'Item 3', id: 3, order: 2}, 
     {name: 'Item 4', id: 4, order: 3}, 
     {name: 'Item 5', id: 5, order: 4}, 
     {name: 'Item 6', id: 6, order: 5}, 
     ], 
    } 
    }, 
    ready() { 
    var vm = this; 
    Sortable.create(document.getElementById('sort'), { 
     draggable: 'li.sort-item', 
     ghostClass: "sort-ghost", 
     animation: 80, 
     onUpdate: function(evt) { 
     console.log('dropped (Sortable)'); 
     vm.reorder(evt.oldIndex, evt.newIndex); 
     } 
    }); 
    }, 
    methods: { 
    reorder(oldIndex, newIndex) { 
     // move the item in the underlying array 
     this.list.splice(newIndex, 0, this.list.splice(oldIndex, 1)[0]); 
     // update order properties based on position in array 
     this.list.forEach(function(item, index){ 
     item.order = index; 
     }); 
    } 
    } 
}); 

Вы можете оптимизировать метод reorder(), если вам нужно.

Адрес updated version of your jsfiddle.

Я чувствую, что это такая функциональность, которую нужно попробовать упаковать в пользовательскую директиву, но я еще не понял, как это сделать.

+0

То сделали работу хорошо. Благодаря :) –

1

Я создал директиву Vue.js ic для обработки такого рода обновлений в общем виде. Его можно использовать точно так же, как директива v-for, но добавить емкость перетаскивания и соответствующие обновления в массиве модели представления.

Использование:

<div v-dragable-for="element in list">{{element.name}}</div> 

Демо:

Example.

Fiddle: example 1, example 2

GitHub: Vue.Dragable.For