参考:
场景:
使用sortable进行拖拽后,视图发生了改变,但是Vue中负责渲染视图的数据和视图不一致,更新渲染数据后会导致重新渲染,VDOM和真实dom不一致又会导致,渲染后把拖拽的视图结果复原。
解决方案:
sortable只负责采集信息,采集信息结束后恢复由于采集信息导致的视图变化,确保视图始终由Vue控制渲染
const targetContainer = document.getElementsByClassName('ant-spin-container')
const _this = this
/* eslint-disable no-new */
const itemContainer = targetContainer[0]
new Sortable(itemContainer, {
animation: 150, // 排序动画的时间
forceFallback: false, // 使用h5原生拖放
// 排序发生变化后执行
onUpdate: event => {
const newIndex = event.newIndex
const oldIndex = event.oldIndex
const newItem = itemContainer.children[newIndex]
const oldItem = itemContainer.children[oldIndex]
// 修改数据顺序
const tempData = _this.data.map(item => ({ id: item.id }))
const newData = exchangeIndex(tempData, newIndex, oldIndex)
// 更新到后端
orderGroup(newData).then(result => {
// 解决vdom和真实dom不一致导致的拖拽回跳
// sortable只负责采集信息,采集信息结束后恢复由于采集信息导致的视图变化,确保视图始终由Vue控制渲染
itemContainer.removeChild(newItem)
if (newIndex > oldIndex) {
itemContainer.insertBefore(newItem, oldItem)
} else {
itemContainer.insertBefore(newItem, oldItem.nextSibling)
}
const sortResult = sortByOrder(result.data)
this.data = sortResult // 更新缓存顺序
this.dataSource = sortResult // 更新渲染顺序
}).catch(err => {
console.log(err)
})
},
})