[VUE2]基于vuedraggable实现拖拽排序卡片

[VUE2]基于vuedraggable实现拖拽排序卡片

vue transition 参考:https://cn.vuejs.org/v2/api/#transition-group

vuedraggable参考: https://www.npmjs.com/package/vuedraggable

更全的vuedraggable中文文档:https://www.itxst.com/vue-draggable/tutorial.html

Vue.Draggable是一款基于Sortable.js实现的vue拖拽插件。支持移动设备、拖拽和选择文本、智能滚动,可以在不同列表间拖拽、不依赖jQuery为基础、vue2过渡动画兼容、支持撤销操作,总之是一款非常优秀的vue拖拽组件。

所有的api

属性名称说明
group:group= “name”,相同的组之间可以相互拖拽 或者 { name: “…”, pull: [true, false, ‘clone’, array , function], put: [true, false, array , function] }
sort:sort= “true”,是否开启内部排序,如果设置为false,它所在组无法排序,在其他组可以拖动排序
delay:delay= “0”, 鼠标按下后多久可以拖拽
touchStartThreshold鼠标移动多少px才能拖动元素
disabled:disabled= “true”,是否启用拖拽组件
animation拖动时的动画效果,还是很酷的,数字类型。如设置animation=1000表示1秒过渡动画效果
handle:handle=“.mover” 只有当鼠标移动到css为mover类的元素上才能拖动
filter:filter=“.unmover” 设置了unmover样式的元素不允许拖动
draggable:draggable=“.item” 那些元素是可以被拖动的
ghostClass:ghostClass=“ghostClass” 设置拖动元素的占位符类名,你的自定义样式可能需要加!important才能生效,并把forceFallback属性设置成true
chosenClass:ghostClass=“hostClass” 被选中目标的样式,你的自定义样式可能需要加!important才能生效,并把forceFallback属性设置成true
dragClass:dragClass="dragClass"拖动元素的样式,你的自定义样式可能需要加!important才能生效,并把forceFallback属性设置成true
dataIdAttrdataIdAttr: ‘data-id’
forceFallback默认false,忽略HTML5的拖拽行为,因为h5里有个属性也是可以拖动,你要自定义ghostClass chosenClass dragClass样式时,建议forceFallback设置为true
fallbackClass默认false,克隆的DOM元素的类名
allbackOnBody默认false,克隆的元素添加到文档的body中
fallbackTolerance拖拽之前应该移动的px
scroll默认true,有滚动区域是否允许拖拽
scrollFn滚动回调函数
scrollSensitivity距离滚动区域多远时,滚动滚动条
scrollSpeed滚动速度

vue2中的使用

一般搭配Vue自带的transition-group组件使用。

<draggable
           class="list-group"
           tag="ul"
           group="list1"
           v-model="flow"
           v-bind="dragOptions"
           @start="dragStart"
           @end="dragEnd"
           >
    <transition-group type="transition" :name="!drag ? 'flip-list' : null">
        <a-card></a-card>
    </transition-group>
</draggable>
<script>

    import draggable from 'vuedraggable'
    export default {
        components: {
            draggable
        },
        data: {
            ...
            drag: false
        },
        methods: {
            dragStart() {
                console.log('顺序', this.$refs.childComponent)
                console.log(this.flow)
                this.drag = true
            },
            dragEnd() {
                console.log('顺序', this.$refs.childComponent)
                console.log(this.flow)
                this.drag = false
            },  
        },
        computed: {
            dragOptions() {
                return {
                    animation: 200,
                    group: 'description',
                    disabled: false,
                    ghostClass: 'ghost'
                }
            }
        },

    }
</script>

<style>
    .flip-list-move {
        transition: transform 0.5s;
    }
</style>

vue3中的使用

<template>
  <div class="main">
    <draggable
        :disabled="!isDraggable"
        class="list-group"
        v-model="listCopy"
        item-key="index"
        @start="drag = true"
        @end="drag = false"
        ghost-class="ghost"
        :animation="200"
    >
      <template #item="{ element, index}">

        <div class="list-group-item">
          <p><span>[{{ index + 1 }}] </span><span>{{ element.name }}</span></p>
          <el-button @click="handleDel(element)" size="small">
            删除
          </el-button>
        </div>

      </template>
    </draggable>
  </div>
</template>

<script setup>
import {ref, toRefs, onMounted} from "vue"
import draggable from "vuedraggable"

const props = defineProps({
  list: {
    type: Array,
    default: () => [
      {
        id: 1,
        name: 1
      },
      {
        id: 2,
        name: 2
      },
      {
        id: 3,
        name: 3
      },
      {
        id: 4,
        name: 4
      }
    ]
  },

  // 是否允许拖拽
  isDraggable: {
    type: Boolean,
    default: true
  }
})


const listCopy = ref(props.list)
const emit = defineEmits(['delete'])

const drag = ref(false)
// const list = ref()


const handleDel = (val) => {
  console.log(val)
  emit("delete", val);
}


onMounted(() => {
  console.log(props.list)
})


</script>

<style scoped>

.main {
  /*border: 1px solid black;*/
  width: 100%;

}

.wrapper {
  display: flex;
  justify-content: center;
  width: 100%;
}

.item {
  width: 100%;
  margin: 5px 0;
  font-size: 20px;
  text-align: center;
  padding: 10px;
  border: 2px solid black;
  background-color: #42b983;
  color: #ffffff;
}


.button {
  margin-top: 35px;
}

.flip-list-move {
  transition: transform 0.5s;
}

.no-move {
  transition: transform 0s;
}

.ghost {
  opacity: 0.5;
  background: #c8ebfb;
}

.list-group {

  min-height: 20px;
}

.list-group-item {
  margin: 0 0 10px;
  cursor: move;
  font-size: 16px;
  text-align: center;
  padding: 5px;
  border: 1px solid black;
  background-color: #EEEEEE;
  /*color: #ffffff;*/

  display: flex;
  justify-content: space-between;
  align-items: center;
}

.list-group-item i {
  cursor: pointer;
}
</style>
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值