首页 > 解决方案 > Vue 可拖动的第二个列表不保持排序

问题描述

我收到一份新订单列表,并将它们垂直显示在 A 列中。第二列 B 显示了当前按个人需要排序的优先列表。当我将一个项目从 A 列拖到 B 列时,它确实移动了该项目,这很好。但是,它可以正确预览,但是当被丢弃时,新项目总是会出现在 B 列的底部。

我正在使用这个组件来获得拖放功能。

是我正在谈论的一个例子/证明。

即使项目在 B 列中并且我想将它们拖放到该列中,它们也可以很好地预览,但在释放鼠标按钮时不会停留。

我可以使用以下代码解决这个内部排序问题(尽管我相信这应该是代码在没有我进行更改的情况下所做的事情。):

在可拖动对象上添加以下事件处理程序:

v-on:end="end"

在 JS 代码中,捕捉事件:

end(e) {
  this.prioritizedNewOrders.splice(e.newIndex, 0, this.prioritizedNewOrders.splice(e.oldIndex, 1)[0]);
}

不过,这仍然不能解决初始拖入 B 列的问题。

答案 @sphinx 的答案是正确的! 是答案的更新小提琴。

标签: vue.jsdraggablerubaxa-sortable

解决方案


查看Vue-draggable: slot

使用页脚槽在 vuedraggable 组件内添加不可拖动元素。

重要提示:它应该与可拖动选项一起使用来标记可拖动元素。请注意,页脚插槽将始终添加在默认插槽之后。

所以添加slot="footer"并将其放在默认插槽之后,然后工作正常。

Vue.config.productionTip = false
new Vue({
  el: "#app",
  data: {
    todos: [
      { id: 1, text: "Learn JavaScript", done: false },
      { id: 2, text: "Learn Vue", done: false },
      { id: 3, text: "Play around in JSFiddle", done: true },
      { id: 4, text: "Build something awesome", done: true }
    ],
    newTodos: []
  },
  methods: {

  }
})
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

del {
  color: rgba(0, 0, 0, 0.3);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<!-- CDNJS :: Sortable (https://cdnjs.com/) -->
<script src="//cdn.jsdelivr.net/npm/sortablejs@1.7.0/Sortable.min.js"></script>

<!-- CDNJS :: Vue.Draggable (https://cdnjs.com/) -->
<script src="//cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/2.16.0/vuedraggable.min.js"></script>

<!-- CDNJS :: Sortable (https://cdnjs.com/) -->
<script src="//cdn.jsdelivr.net/npm/sortablejs@1.7.0/Sortable.min.js"></script>

<!-- CDNJS :: Vue.Draggable (https://cdnjs.com/) -->
<script src="//cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/2.16.0/vuedraggable.min.js"></script>

<div id="app">

<p><i>Drag things from the "New Orders" list to the "Prioritized Orders" list. You will see that they sort fine while they are in the New Orders list.  But when you drag them to be a certain location (not the last spot) on the Prioritized Order list, they ALWAYS jump to the bottom.  Even though you can "See" that they will show up where you want them until you let go of the mouse.</i></p><br />
<p>
<i>Also, sorting works great in the New Orders list.  But once items are in the Prioritized list, they show that it will look good until you let go of the mouse.</i>
<br /><br />Adding this code to the "end" event will fix the sorting.  But IMHO, this should work without ME coding anything:<br /><br />
<div style="font-family: 'courier-new'">
this.prioritizedNewOrders.splice(e.newIndex, 0, this.prioritizedNewOrders.splice(e.oldIndex, 1)[0]);
</div>
</p><br />
<!-- New Items -->
<div class="d-flex justify-content-between">
	<b>New Orders - Not yet Prioritized</b>
	<label>{{ todos.length }}</label>
</div>

<draggable v-model="todos"
					 v-bind:options="{ group: { name: 'Orders', pull: true } }">
	<div style="border: 1px solid #ccc; margin-bottom: 3px;"
			 v-for="o in todos"
			 v-bind:key="o.id">
		<div style="padding: 1rem;">
			<label>{{ o.text }}</label><br />
			<label>{{ o.done }}</label>
		</div>
	</div>
</draggable>

<!-- Ordered Queue -->
<br />
<div>
	<b>Prioritized Orders Queue</b>
	<label>{{ newTodos.length }}</label>
</div>

<div class="prioritized-new-orders" style="border: 1px solid #ccc; background-color: #eee;">
	<draggable v-model="newTodos"
						 v-bind:options="{ group: { name: 'Orders', put: true }, animation: 250 }">
		<div style="border: 1px solid #ccc; margin-bottom: 3px;"
				 v-for="o in newTodos"
				 v-bind:key="o.id">
			<div style="padding: 1rem;">
				<label>{{ o.text }}</label><br />
				<label>{{ o.done }}</label>
			</div>
		</div>
		<p slot="footer" class="text-info p-3 mb-0" v-if="newTodos.length === 0">Drag and Drop New Orders from the left column here to Prioritize them.</p>
	</draggable>
</div>

</div>


推荐阅读