Sortable拖拽表格顺序错乱问题解决

发布于 分类: 各种框架 285

根本原因

根本原因是Virtual DOM和真实DOM之间出现了不一致。

所以在Vue2.0以前,因为没有引入Virtual DOM,这个问题是不存在的。

在使用Vue框架的时候要尽量避免直接操作DOM

解决办法

1、通过设置table表格的row-key唯一标志每一个VNode,

<el-table :data="tableList"  ref="dragTable"  :row-key="getRowKeys" >
 data () {
    return {
      getRowKeys (row) {
        return row.id
      },
 }


2、因为根本原因是真实DOM和VNode不一致,所以可以通过把拖拽移动真实DOM的操作还原,即在回调函数里,把[$B,$A,$C,$D]还原成[$A,$B,$C,$D],让DOM的操作交还给Vue

 // 创建sortable实例
    initSortable () {
      let _this = this
      // 获取表格row的父节点
      const ele = this.$refs.dragTable.$el.querySelector(
        '.el-table__body > tbody'
      )
      // 创建拖拽实例
      let dragTable = Sortable.create(ele, {
        animation: 150, // 动画
        disabled: false, // 拖拽不可用? false 启用(刚刚渲染表格的时候起作用,后面不起作用)
        handle: '.move', // 指定拖拽目标,点击此目标才可拖拽元素(此例中设置操作按钮拖拽)
        filter: '.disabled', // 指定不可拖动的类名(el-table中可通过row-class-name设置行的class)
        dragClass: 'dragClass', // 设置拖拽样式类名
        ghostClass: 'ghostClass', // 设置拖拽停靠样式类名
        chosenClass: 'chosenClass', // 设置选中样式类名
        onUpdate: function (event) {
          var newIndex = event.newIndex
          var oldIndex = event.oldIndex
          var $li = ele.children[newIndex]
          var $oldLi = ele.children[oldIndex]
          ele.removeChild($li)
          // 再插入移动的节点到原有节点,还原了移动的操作
          if (newIndex > oldIndex) {
            ele.insertBefore($li, $oldLi)
          } else {
            ele.insertBefore($li, $oldLi.nextSibling)
          }
          // 更新items数组
          var item = _this.tableList.splice(oldIndex, 1)
          _this.tableList.splice(newIndex, 0, item[0])
          _this.jisuanFn()
        },
        // 开始拖动事件
        onStart: () => {
        },
        // 结束拖动事件
        onEnd: ({ newIndex, oldIndex }) => {
        
        }
      })
    },


赞 888

关于作者:xiaona

一个喜欢研究的前端工程师。

请进入“Zblog后台” -> “畅言” 登陆你的畅言账号。