如何使用sortablejs拖拽库并封装成组件

 sortablejs 拖拽库可看详细配置

//安装
npm install sortablejs --save
//引入
import Sortable from 'sortablejs'; 

使用
 1. 获取要拖动的列表元素 (只要能获取到元素即可)

 var el = document.querySelector('.container');


 2. 配置
    var sortable = Sortable.create(el,{配置内容})

组件封装

//component/sortable.vue
<template>
  <div class="sort-table">
    <slot :colData="colData" :dropColData="dropColData"/>
  </div>
</template>
<script>
import Sortable from 'sortablejs'
export default {
//trClass用于选择要拖动的标签 className指定样式类的元素才允许拖动
  props: ['col', 'initFlag', 'trClass', 'className'],
  name: 'sortable',
  data() {
    return {
      dropCol: [], // 拖动所需要的th和td,与上面数组一样
      isMounted: false,
    }
  },
  mounted() {
    this.isMounted = true
    if (this.initFlag === undefined || this.initFlag > 0) this.init()
  },
  computed: {
    /* 当前展示的列数组 */
    colData() {
      let colData = this.col.filter(v => v.label !== '')
      return colData
    },
    /* 要拖动的列数组 */
    dropColData() {
      let dropColData = this.dropCol.filter(v => v.label !== '')
      return dropColData
    }
  },
  methods: {
    init() {
      if (!this.isMounted) return
      /* 阻止默认行为 */
      document.body.ondrop = function (event) {
        event.preventDefault();
        event.stopPropagation();
      };
      this.columnDrop()
    },
    /* 列拖拽 */
    columnDrop () {
      const tr = document.querySelector(this.trClass || '.el-table__header-wrapper tr')
      this.sortable = Sortable.create(tr, {
        animation: 180, // 过度动画
        delay: 0, // 延迟多久可以拖动
        filter: ".cannotDrag", // 过滤或忽略指定元素
        draggable: this.className, // 指定样式类的元素才允许拖动
        onEnd: evt => { // 拖动结束后的事件
          const oldItem = this.dropCol[evt.oldIndex]
          this.dropCol.splice(evt.oldIndex, 1)
          this.dropCol.splice(evt.newIndex, 0, oldItem)
        }
      })
    },
  },
  watch: {
    initFlag: {
      immediate: true,
      handler(newVal) {
        if (newVal === undefined) return this.init()
        if (newVal > 0) this.init()
      },
    },
    col: {
      deep: true,
      immediate: true,
      handler(newVal) {
        this.dropCol = JSON.parse(JSON.stringify(newVal))
      },
    },
  },
}
</script>
<style lang="scss">
.sort-table {
  padding: 0 10px;
  .el-input__icon {
    line-height: 0;
  }
}
</style>

使用

<template>
 <sortable
   :col="col"
   :initFlag="initFlag"
   trClass=".table-header-tr"
   className=".canDrag"
  >
   <template slot-scope="sortableScope">
         <el-table
              :data="Data"
              border
              style="width: 100%"
          >
            <el-table-column
                class-name="cannotDrag"
                type="index"
                label="序号"
                width="50"
                align="center"
            ></el-table-column>
            <el-table-column
                v-for="(item, index) in sortableScope.colData"
                :key="`col_${index}`"
                :prop="sortableScope.dropColData[index].prop"
                :label="item.label"
                :min-width="item.width"
                :class-name="'canDrag_pop'"
                align="center"
                show-overflow-tooltip
            >
              <template slot-scope="scope">
                <el-link
                    v-if="sortableScope.dropColData[index].prop === 'address'"
                    type="primary"
                    :underline="false"
                >{{scope.row.address}}
                </el-link>
                <template
                    v-else
                    type="text"
                    class="btn-text"
                >{{scope.row[sortableScope.dropColData[index].prop]}}
                </template>
              </template>
            </el-table-column>
          </el-table>
   </template>
 </sortable>
</template>

import sortable from '@/components/sortable'
data() {
    return {
   col: [ // th和对于的td字段
        {
          label: '', // label为空的表示为序号和checkbox,占位
          prop: ''
        },
        {
          label: '姓名',
          prop: 'name',
          width: '120'
        },
        {
          label: '时间',
          prop: 'date',
          width: '120'
        },
        {
          label: '地址',
          prop: 'address',
          width: '120'
        }
        ],
    Data: [{
            date: '2016-05-02',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1518 弄'
          }, {
            date: '2016-05-04',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1517 弄'
          }]
      }
       },
 computed: {
    initFlag() {
      if (this.dialogTableVisible) return +new Date()
      else return 0
    }
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值