< div class = "drag" > < div class = "col-md-3" > < draggable class = "list-group" tag = "div" v-model = "list" v-bind = "dragOptions" :move = "onMove" @ start = "isDragging=true" @ end = "isDragging=false" > < transition-group type = "transition" :name = "'flip-list'" > < div class = "item" v-for = "element in list" :key = "element.order" > < i :class = "element.fixed? 'fa fa-anchor' : 'glyphicon glyphicon-pushpin'" @ click = " element.fixed=! element.fixed" aria-hidden = "true" /> {{element.name}} < span class = "badge" > {{element.order}} </ span > </ div > </ transition-group > </ draggable > </ div > < div class = "col-md-3" > < draggable element = "span" v-model = "list2" v-bind = "dragOptions" :move = "onMove" > < transition-group name = "no" class = "list-group" tag = "ul" > < div class = "item" v-for = "element in list2" :key = "element.order" > < i :class = "element.fixed? 'fa fa-anchor' : 'glyphicon glyphicon-pushpin'" @ click = " element.fixed=! element.fixed" aria-hidden = "true" > </ i > {{element.name}} < span class = "badge" > {{element.order}} </ span > </ div > </ transition-group > </ draggable > </ div > </ div > </ template > < script > import draggable from "vuedraggable" ; const message = [ "vue.draggable" , "draggable" , "component" , "for" , "vue.js 2.0" , "based" , "on" , "Sortablejs" export default { components : { draggable data ( ) { return { list : message. map ( ( name, index ) => { return { name, order : index + 1 , fixed : false }; list2 : [], editable : true , isDragging : false , delayedDragging : false computed : { dragOptions ( ) { return { animation : 300 , group : "description" , disabled : ! this . editable , ghostClass : "ghost" </ script >

ps:vuedraggable这个包里引入了 element-ui,所以万一项目本身很大的话,还是不推荐使用了吧,不然打的包又要大很多。

2. 使用 draggable 属性 + transition-group

draggable:一个元素可以被拖放需要设置 draggable 属性为 true (文本、图片和链接的 draggable 默认就是 true )

<div draggable="true">能被拖放的元素</div>

设置了这个属性的元素就能实现拖拽效果了,但是实现拖拽并放置还不行,还需要处理配合其他方法,如下:

触发对象事件名称说明
源对象dragstart源对象开始被拖动时触发
drag源对象被拖动过程中反复触发
dragend源对象拖动结束时触发
目标对象dragstart源对象开始进入目标对象范围内触发
dragover源对象在目标对象范围内移动时触发
dragleave源对象离开目标对象范围时触发
drop源对象在目标对象范围内被释放时触发
<template>
    // transition-group 使拖拽效果更加流畅
    <transition-group class="trans" name="trans-list" tag="div">
        // 遍历元素,给每个元素添加 draggable 属性
        <div class="item" v-for="(item,index) in apps" :key="item.order"  :draggable="item.fixed ? false : true" @dragstart="drag($event,index,item)" @dragend="dragend($event)" @dragenter="dragenter($event)" @dragleave="dragleave($event)" @dragover="allowDrop($event)" @drop="drop($event,index)">
          <span @click.stop.prevent="changeMove(item)">{{item.fixed ? '固定' : '可动'}}</span>
          {{item.title}}
        </div>
    </transition-group>
  </div>
</template>
<script>
import _ from 'lodash'
export default {
  name:'hardWorld',
  data(){
    return{
      apps:[
          title:'空我',
          order:1
          title:'亚吉托',
          order:2
          title:'龙骑',
          order:3
          title:'555',
          order:4
          title:'剑',
          order:5
          title:'响鬼',
          order:6
          title:'甲斗',
          order:7
          title:'电王',
          order:8
          title:'月骑',
          order:9
          title:'帝骑',
          order:10
      // 当前拖拽元素的下标
      indexS:null,
  methods:{
    // 修改元素 draggable 属性,false为不能拖拽
    changeMove(data){
      this.$set(data,'fixed',!data.fixed)
    // 拖拽,保存当前拖拽元素的下标
    // 更改拖拽元素的透明度,使其与其他元素从视觉上区分开来
    drag(e,index,data){
      if(data.fixed){
        return
      this.indexS = index;
      e.target.style.opacity = 0.5;
    // 拖拽结束,拖拽元素的半透明度去掉,恢复原状
    dragend(e){
      e.target.style.opacity ='';
    // 拖拽元素进入当前节点范围时,给目标元素添加一个背景色
    dragenter(e){
      if (e.target.className === 'item') {
        e.target.style.background = 'purple';
    // 拖拽元素离开当前节点范围时,去掉背景色
    dragleave(e){
      if (e.target.className === 'item') {
        e.target.style.background = '';
    // 拖拽元素在当前节点范围内移动时触发
    // 阻止目标节点触发默认操作
    allowDrop(e){
      e.preventDefault()
    // 释放拖拽元素,获取目标元素的下标
    // 将拖拽元素原位置的值进行删除,并将其插入至新目标元素的位置
    drop(e,index){
      e.preventDefault();
      e.target.style.background = '';
      let moved=_.cloneDeep(this.apps[this.indexS])
      let moveTarget=_.cloneDeep(this.apps[index])
      if (index>-1 && index!==this.indexS && !moveTarget.fixed) {
        this.apps.splice(this.indexS,1)
        this.apps.splice(index,0,moved)
</script>
<style scoped>
.trans{
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
.trans-list-move{
  transition: transform .3s;
.item{
  width:19%;
  margin: 5px 0;
  background-color: #eee;
</style>

简单的拖拽demo就完成了,当然还能在这基础上实现更好的效果,可以随意发挥!

分类:
前端