draglistVue简单封装2021-07-07

dragable组件 基于 Sortable的简单封装

<template>
  <div :id="id"
       class="list-group">
    <slot></slot>
  </div>
</template>

<script>
import Sortable, { MultiDrag } from 'sortablejs';
Sortable.mount(new MultiDrag());
export default {
  props: {
    id: String,
    group: {
      type: Object,
      default: () => { return {} }
    },
    multi: {
      type: Boolean,
      default: false
    },
    selectedClass: {
      type: String,
      default: 'selected'
    },
    sort: {
      type: Boolean,
      default: true
    }
  },
  data () {
    return {
      groupName: 'share'
    }
  },
  mounted () {
    this.group['name'] = this.group['name'] || this.groupName
    var el = document.getElementById(this.id);
    new Sortable(el, {
      group: this.group,
      multiDrag: this.multi, // Enable the plugin
      selectedClass: this.selectedClass, // Class name for selected item
      multiDragKey: "CTRL",
      ghostClass: 'yellow-background-class',
      sort: this.sort,
      delay: 0,
      setData: (dataTransfer, dragEl) => { this.invoke('setdata', dataTransfer, dragEl) },
      onChoose: (evt) => { this.invoke('choose', evt) },
      onStart: (evt) => { this.invoke('start', evt) },
      onEnd: (evt) => { this.invoke('end', evt) },
      onAdd: (evt) => { this.invoke('add', evt) },
      onUpdate: (evt) => { this.invoke('update', evt) },
      onSort: (evt) => { this.invoke('sort', evt) },
      onRemove: (evt) => { this.invoke('remove', evt) },
      onMove: (evt, originalEvent) => { this.invoke('move', evt, originalEvent) },
      onClone: (evt) => { this.invoke('clone', evt) },
      onChange: (evt) => { this.invoke('change', evt) },
      onFilter: (evt) => { this.invoke('filter', evt) },
    });
  },
  methods: {
    invoke (name, ...args) {
      this.$emit(name, ...args)
    }
  },
}
</script>

<style scoped>
.selected {
  border: 1px solid red;
  background-color: bisque;
}
.yellow-background-class {
  background: #ddd;
}
</style>

基于dragable封装的list组件,支持vue.draggable大多属性设置。

<template>
  <dragable-vue :id="dragid"
                :group="group"
                v-bind="$attrs"
                @start="onStart"
                @add="onAdd">
    <div v-for="(item,index) in valuelist"
         :key="index"
         :data-value="item[Itemkey]">
      <slot name="item"
            :row="item"></slot>
    </div>
  </dragable-vue>
</template>

<script>
import dragableVue from './dragable.vue'
var transfer_data_ = []
function removeNode (node) {
  if (node.parentElement !== null) {
    node.parentElement.removeChild(node);
  }
}
export default {
  components: {
    dragableVue
  },
  props: {
    value: Array,
    group: Object,
    unique: {
      type: Boolean,
      default: false
    },
    Itemkey: String
  },
  data () {
    return {
      valuelist: [],
      dragid: `group${Math.random().toString(36).substr(2, 15)}`
    }
  },
  watch: {
    value (newvalue) {
      this.valuelist = newvalue
    }
  },
  methods: {
    onStart (evt) {
      let indexs = evt.oldIndicies.length ? evt.oldIndicies.map(item => item.index) : [evt.oldIndex]
      transfer_data_ = indexs.map(key => this.valuelist[key])
    },
    onAdd (evt) {
      let index = evt.newIndex
      let children = evt.newIndicies.length ? evt.newIndicies.map(item => item.multiDragElement) : [evt.item]
      children.forEach(el => {
        removeNode(el)
      });
      let keys = this.valuelist.map(item => item[this.Itemkey]),
        tempdata = this.unique ? transfer_data_.filter(item => !keys.includes(item[this.Itemkey])) : transfer_data_
      this.valuelist.splice(index, 0, ...tempdata)
      this.$emit("input", this.valuelist)
    }
  }
}
</script>
<style scoped>
</style>

简单测试和使用:

<template>
  <div>
    <div class="text">
      <draglist-vue :group="{pull:'clone',put:false}"
                    :multi="true"
                    :sort="false"
                    class="text-item"
                    Itemkey="value"
                    v-model="list1">
        <template #item="{row}">
          <span v-text="row.label"> </span>
        </template>
      </draglist-vue>
      <draglist-vue v-model="list2"
                    :unique="true"
                    Itemkey="value"
                    class="text-item">
        <template #item="{row}"><span v-text="row.label"> </span></template>
      </draglist-vue>
    </div>
    <button @click="handleClick">点我看结果</button>
  </div>
</template>

<script>
import draglistVue from './draglist.vue'
export default {
  components: {
    draglistVue,
  },
  data () {
    return {
      list1: [],
      list2: []
    }
  },
  mounted () {
    this.list1 = [...new Array(10).keys()].map(key => {
      let temp = "Item" + key
      return { label: temp, value: temp }
    })
    this.list2 = [...new Array(2).keys()].map(key => {
      let temp = "Item" + key
      return { label: temp, value: temp }
    })
  },
  methods: {
    handleClick () {
      console.log(this.list2)
    }
  },
}
</script>

<style scoped>
.text {
  display: flex;
  justify-content: space-between;
}
.text-item {
  width: 40%;
}
li {
  height: 30px;
  background-color: aquamarine;
  margin-top: 5px;
}
</style>

版本:
“sortablejs”: “^1.14.0”,
“vue”: “^2.5.2”,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值