【问题标题】:Vue Draggable view is out of sync with modelVue Draggable 视图与模型不同步
【发布时间】:2018-02-09 22:23:12
【问题描述】:

我正在开发一些拖放功能,由于某种原因,我的视图似乎与我的模型不同步。对于我列表中的某些项目,我希望它们不可拖动并保持在它们的设定位置。当我尝试将可拖动项目移动到另一个之前,我的不可拖动项目会从该位置移动。我创建了一个 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);
  }
}

【问题讨论】:

  • 非常奇怪的东西。我剥离了很多东西,仍然得到了加扰行为。此外,当数组更改时,我将数组列出到控制台,并且它的顺序与视图中的不同。 jsfiddle.net/2tyqjppq/9

标签: javascript vue.js draggable sortablejs


【解决方案1】:

实现这一目标的最接近方法是取消移动(参考:How to cancel a drag)。

这不会为您提供完全相同的用户体验,因为不可拖动元素确实开始拖动,但它们不会完成移动。

模板

<draggable class="warp-div" 
  :list="myArray" 
  :options="{group:'alphabet', draggable:'.div'}" 
  :move="onMoveCallback">

组件

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

JSFiddle


混合索引

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

您可以通过点击 @sort="onSort" 事件来查看这一点 - event.oldIndex 和 event.newIndex 反映 具有 .element-draggable 类的元素的子列表中的位置 ,即项目“B”和“C”。

@change="onChange" 方法接收 Vue 版本的 oldIndex,但接收 Sortable 版本的 newIndex。显示在 onChange 运行之前更新(请参阅 $emit 在 $nextTick 中),因此使用此挂钩看起来不可行。

vuedraggable.js

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)
  });
},

【讨论】:

  • 那么,如何解决“混合索引”问题?
猜你喜欢
  • 2012-12-04
  • 2011-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-08
  • 2018-01-31
相关资源
最近更新 更多