Vue Draggable视图与模型不同步

时间:2018-02-09 22:23:12

标签: javascript vue.js draggable sortablejs

我正在研究一些拖放功能,出于某种原因,我的视图似乎与我的模型不同步。对于我列表中的一些项目,我希望它们不会被拖动并保持在他们的固定位置。当我尝试将可拖动项目移动到另一个不可拖动项目之前然后从该位置移动。我创建了一个JSFiddle来帮助解释https://jsfiddle.net/2tyqjppq/8/。用例是将值C移到B之前,我期望的顺序是AZCB,但实际值是ABZ C.我应该注意,我的意思是绑定到计算属性,而不是针对拖动+的情况下的模型drop是无效的,这样可以更容易恢复。

数据

myArray: [
    {'name': 'A'},
    {'name': 'Z'},
    {'name': 'B'},
    {'name': 'C'}
  ]

可拖动的

 <draggable class="warp-div" :list="getElements" :options="{group:'people', draggable:'.element-draggable'}"
@change="onChange">
  <div class="div" :class="[element.name === 'A' || element.name === 'Z' ? '' : 'element-draggable']" :style="'background-color:'+element.color" v-for="element in myArray">{{element.name}}</div>
</draggable>

计算属性

getElements () {
  console.log('getting list elements');
  console.log(this.myArray);
  const temp = this.myArray.map(t => t);
  return temp;
}

更新模型的方法

onChange (event) {
    if (event.moved) {
    const element = event.moved.element;
    console.log(element.name);

    // +2 to insert into myArray[2] as non draggable items are in spots 0,1
    const indexToInsert = event.moved.newIndex + 2;
    console.log(indexToInsert);

    //remove element from model
    for (let i = 0; i < this.myArray.length; i++) {
        if (this.myArray[i].name === element.name) {
        this.myArray.splice(i, 1);
      }
    }

    // insert element into proper place
    this.myArray.splice(indexToInsert, 0, element);
    console.log('Finished onChange');
    console.log(this.myArray);
  }
}

1 个答案:

答案 0 :(得分:0)

你可以达到最接近的目的是取消移动(参考:How to cancel a drag)。

这并没有给你完全相同的用户体验,因为不可拖动的元素确实开始拖动,但它们没有完成移动。

<强>模板

methods: {
  onMoveCallback: function(evt, originalEvent) {
    return evt.dragged.classList.contains('element-draggable');
  },

<强>组件

@sort="onSort"

JSFiddle

混合索引

当列表部分可拖动时(即只有部分元素具有可拖动类),可排序内部列表与Vue列表不同。

您可以通过点击@change="onChange"事件来看到这一点 - event.oldIndex和event.newIndex反映了 元素子列表中位置的.element-draggable class ,即项目&#39; B&#39;和&#39; C&#39;。

onDragUpdate(evt) { removeNode(evt.item) insertNodeAt(evt.from, evt.item, evt.oldIndex) const oldIndex = this.context.index const newIndex = this.getVmIndex(evt.newIndex) this.updatePosition(oldIndex, newIndex) const moved = { element: this.context.element, oldIndex, newIndex } this.emitChanges({ moved }) }, ... emitChanges(evt) { this.$nextTick(() => { this.$emit('change', evt) }); }, 方法接收oldIndex的Vue版本,但是newIndex的Sortable版本。显示在 onChange 运行之前更新(请参阅$ emit在$ nextTick中),因此使用此挂钩看起来不可行。

<强> vuedraggable.js

{{1}}
相关问题