Vue Draggable视图与模型不同步,非可拖拽项移位求助
解决Vue Draggable视图与模型不同步及固定非拖拽项位置的问题
嘿,我帮你搞定这个Vue Draggable的坑!你遇到的问题其实是默认配置下,即便标记了部分项不可拖拽,拖拽其他项时还是会直接修改整个数组的顺序,导致非拖拽项被“挤”移位,同时还可能因为拖拽逻辑和响应式更新的配合问题,出现视图和模型不同步的情况。
下面给你具体的解决方案,分步骤来:
1. 正确配置不可拖拽项的过滤规则
首先要利用Vue Draggable自带的filter和preventOnFilter属性,精准标记不可拖拽的元素,并且阻止对这些元素的拖拽触发行为:
<vuedraggable v-model="list" :filter=".non-draggable" <!-- 指定不可拖拽元素的class --> preventOnFilter="true" <!-- 阻止点击非拖拽项时触发拖拽 --> > <div v-for="item in list" :key="item.id" :class="{ 'non-draggable': !item.draggable }" > {{ item.value }} </div> </vuedraggable>
这里给不可拖拽的项加上non-draggable类,让Draggable识别并跳过它们。
2. 自定义拖拽位置控制,固定非拖拽项
接下来通过move事件来限制拖拽的放置位置,确保可拖拽项不能插入到非拖拽项的位置,从而固定非拖拽项的顺序:
export default { data() { return { list: [ { id: 1, value: 'A', draggable: true }, { id: 2, value: 'B', draggable: false }, { id: 3, value: 'C', draggable: true }, { id: 4, value: 'D', draggable: false } ] }; }, methods: { handleMove(evt) { // 拿到拖拽的源项和目标位置的项 const draggedItem = this.list[evt.fromIndex]; const targetItem = this.list[evt.toIndex]; // 禁止拖拽不可拖拽项,同时禁止将可拖拽项放到非拖拽项的位置 if (!draggedItem.draggable || !targetItem.draggable) { return false; // 返回false阻止这次拖拽操作 } } } };
记得在vuedraggable上绑定这个事件:@move="handleMove"。这个方法会在每次拖拽移动时触发,一旦检测到目标位置是不可拖拽项,就阻止放置,这样非拖拽项的位置就不会被打乱了。
3. 确保模型与视图的响应式同步
如果还是出现视图和模型不同步的情况,要注意两点:
- 给列表项绑定唯一的key:必须用每个项的唯一标识(比如
id)作为key,不能用索引,否则Vue的列表渲染会出现复用错误。 - 用响应式方式更新数组:如果需要手动修改数组顺序,尽量使用Vue提供的数组方法(比如
splice)或者展开运算符创建新数组,比如:
// 正确的数组更新方式 this.list = [...this.list]; // 或者用splice修改后,Vue会自动追踪变化 this.list.splice(index, 1, newItem);
避免直接通过索引修改数组元素(比如this.list[index] = newItem),这种方式Vue无法追踪到响应式更新。
按照上面的配置,你再测试把C移到B前方的场景,就会发现非拖拽项B不会移位,同时视图和模型的顺序也能保持同步啦!
内容的提问来源于stack exchange,提问作者jkerivan
相关产品推荐
相关产品推荐

