vue里面的拖拽功能大合集

Element UI实现拖拽功能

在Element UI里面我们可以通过Tree树形控件和他的属性draggable来实现
在这里插入图片描述

HTML结构

<el-tree
  :data="data"
  node-key="id"
  default-expand-all
  @node-drag-start="handleDragStart"
  @node-drag-enter="handleDragEnter"
  @node-drag-leave="handleDragLeave"
  @node-drag-over="handleDragOver"
  @node-drag-end="handleDragEnd"
  @node-drop="handleDrop"
  draggable
  :allow-drop="allowDrop"
  :allow-drag="allowDrag">
</el-tree>

js

<script>
  export default {
    data() {
      return {
        data: [{
          id: 1,
          label: '一级 1',
          children: [{
            id: 4,
            label: '二级 1-1',
            children: [{
              id: 9,
              label: '三级 1-1-1'
            }, {
              id: 10,
              label: '三级 1-1-2'
            }]
          }]
        }, {
          id: 2,
          label: '一级 2',
          children: [{
            id: 5,
            label: '二级 2-1'
          }, {
            id: 6,
            label: '二级 2-2'
          }]
        }, {
          id: 3,
          label: '一级 3',
          children: [{
            id: 7,
            label: '二级 3-1'
          }, {
            id: 8,
            label: '二级 3-2',
            children: [{
             id: 11,
              label: '三级 3-2-1'
            }, {
              id: 12,
              label: '三级 3-2-2'
            }, {
              id: 13,
              label: '三级 3-2-3'
            }]
          }]
        }],
        defaultProps: {
          children: 'children',
          label: 'label'
        }
      };
    },
    methods: {
      handleDragStart(node, ev) {
        console.log('drag start', node);
      },
      handleDragEnter(draggingNode, dropNode, ev) {
        console.log('tree drag enter: ', dropNode.label);
      },
      handleDragLeave(draggingNode, dropNode, ev) {
        console.log('tree drag leave: ', dropNode.label);
      },
      handleDragOver(draggingNode, dropNode, ev) {
        console.log('tree drag over: ', dropNode.label);
      },
      handleDragEnd(draggingNode, dropNode, dropType, ev) {
        console.log('tree drag end: ', dropNode && dropNode.label, dropType);
      },
      handleDrop(draggingNode, dropNode, dropType, ev) {
        console.log('tree drop: ', dropNode.label, dropType);
      },
      allowDrop(draggingNode, dropNode, type) {
        if (dropNode.data.label === '二级 3-1') {
          return type !== 'inner';
        } else {
          return true;
        }
      },
      allowDrag(draggingNode) {
        return draggingNode.data.label.indexOf('三级 3-2-2') === -1;
      }
    }
  };
</script>

自认为比较重要的参数

  1. render-after-expand 是否在第一次展开某个树节点后才渲染其子节点
  2. highlight-current 是否高亮当前选中节点,默认值是 false。
  3. default-expand-all 是否默认展开所有节点
  4. allow-drag 判断节点能否被拖拽 需要自己写业务逻辑
  5. draggable 是否开启拖拽节点功能
  6. allow-drop 拖拽时判定目标节点能否被放置。type 参数有三种情况:‘prev’、‘inner’ 和 ‘next’,分别表示放置在目标节点前、插入至目标节点和放置在目标节点后 Function(draggingNode, dropNode, type)
  7. children 指定子树为节点对象的某个属性值
  8. disabled 指定节点选择框是否禁用为节点对象的某个属性值
注意的点

此组件样式比较顽固父级可以拖动到其他父级之中甚至子集之中且判断起来非常麻烦如果数据比较复杂且实现拖拽时较为考究可能就不太合适

vue.draggable实现拖拽功能

Vue.Draggable是一款基于Sortable.js实现的vue拖拽插件。支持移动设备、拖拽和选择文本、智能滚动,可以在不同列表间拖拽、不依赖jQuery为基础、vue 2过渡动画兼容、支持撤销操作。
官方网站https://github.com/SortableJS/Vue.Draggable

在这里以npm为主

1.安装:npm install vuedraggable
2.引入:import draggable from ‘vuedraggable’
3.注册:components: {
   draggable
},

使用
单列拖动

HTML

 <draggable v-model="myArray"  @start="onStart" @end="onEnd">
    <transition-group>
     <div class="item" v-for="item in myArray" :key="item.id">{{item.name}}</div>
    </transition-group>
</draggable>

JS

<script>
//导入draggable组件
import draggable from 'vuedraggable'
export default {
  //注册draggable组件
   components: {
            draggable,
        },
   data() {
    return { 
      drag:false,
      //定义要被拖拽对象的数组
      myArray:[
        {people:'cn',id:10,name:'www.itxst.com'},
        {people:'cn',id:20,name:'www.baidu.com'},
        {people:'cn',id:30,name:'www.taobao.com'},
        {people:'us',id:40,name:'www.yahoo.com'}
        ] 
    };
  },
  methods: {
     //开始拖拽事件
      onStart(){
        this.drag=true;
      },
      //拖拽结束事件
       onEnd() {
       this.drag=false;
    },
  },
};
</script>

CSS

<style scoped>
        /*被拖拽对象的样式*/
        .item {
            padding: 6px;
            background-color: #fdfdfd;
            border: solid 1px #eee;
            margin-bottom: 10px;
            cursor: move;
        } 
        /*选中样式*/
        .chosen {
            border: solid 1px #3089dc !important;
        }
</style>
多层次数据格式实现拖拽

在这里插入图片描述

<script>
import draggable from 'vuedraggable'
export default {
  components: {
    draggable
  },
  data() {
    return {
      tolList: [
        {
          groupName: '获得与消耗',
          children: [
            {
              name: '获得钻石', id: 1
            },{
              name: '获得装备', id: 2
            }
          ]
        }, {
          groupName: '社交功能',
          children: [
            {
              name: '战胜好友BOSS', id: 1
            },{
              name: '添加好友', id: 2
            }
          ]
        }, {
          groupName: '互动付费',
          children: [
            {
              name: '付费成功', id: 1
            }{
              name: '发起付费订单', id: 2
            }
          ]
          }
      ],
      controlOnStart: true
    }
  },
  methods: {
    clone({ name, id }) {
      return { name, id: id }
    },
    pullFunction() {
      return this.controlOnStart ? 'clone' : true
    },
    start({ originalEvent }) {
      this.controlOnStart = originalEvent.ctrlKey
    },
    getNewList() {
      let a = this.tolList
      console.log(a)
    }
  }
}
</script>

HTML

<template>
  <div class="wholeList"  v-for="element in tolList" :key="element.id">
      <div class="leftConLi">
        {{ element.name }}
      </div>
        <draggable
          class="dragArea list-group"
          :list="item.children"
          :clone="clone"
          :group="{ name: 'people', pull: pullFunction }"
          @start="start"
        >
          <div v-for="element in item.children" :key="element.id" class="list-group-item">
            {{ element.name }}
          </div>
        </draggable>
   
  </div>
</template>

如果想要好看的拖动效果可以通过animation属性设置vue.draggable过渡效果。

vue-grid-layout实现拖拽功能

vue-grid-layout是一个非常优秀的vue栅格拖动布局的组件,使用方法请参考
安装:npm install vue-grid-layout --save
引入: import VueGridLayout from ‘vue-grid-layout’

使用

CSS

<template>
    <div class="board" style="width: 100%">
      <div class="home">
        <grid-layout
         :layout="layoutData"
          :col-num="12"
          :row-height="layoutHeight"
          :is-draggable="dialogVisible"
          :is-resizable="dialogVisible"
         :is-mirrored="false"
         :vertical-compact="true"
         :margin="[10, 10]"
         :use-css-transforms="true"
       >
         <grid-item v-for="(item,index) in layoutData"
                    :x="item.x"
                    :y="item.y"
                    :w="item.w"
                    :h="item.h"
                   :i="item.i"
                    :key="item.i"
         >
           {{index}}
         </grid-item>
       </grid-layout>
     </div>
   </div>
 </template>

JS

 export default {
     data() {
       return {
         // 布局数据
         layoutData: [
    {
      "x": 0,
      "y": 0,
      "w": 1,
      "h": 1,
      "i": "0"
    },
    {
      "x": 0,
      "y": 1,
      "w": 1,
      "h": 1,
      "i": "1"
    },
    {
      "x": 0,
      "y": 2,
      "w": 1,
      "h": 1,
      "i": "2"
    },
    {
      "x": 0,
      "y": 3,
      "w": 1,
      "h": 1,
      "i": "3"
    },
    {
      "x": 1,
      "y": 0,
      "w": 1,
      "h": 1,
      "i": "4"
    }
  ],
         layoutConfig: {
           height: 100, // 默认高度
           dialogVisible: false // 是否可拖拽或改变大小
         }
       }
     },
     components: {
       GridLayout,
       GridItem
     },
     methods: {
     },
     created() {
       
     }
   }

一些参数含义

  1. colNum 将一行分为多少块 数字 默认 12
  2. rowHeight 行高 数字 默认是单位是 px
  3. isDraggable 是否可以拖拽 boolean
  4. isResizable 是否可以改变大小 boolean
  5. responsive 是否是响应式的 boolean
  6. i id 类型不限
  7. x 第几列 数字
  8. y 第几行 数字
  9. w 占几块 数字
  10. h 高度 ,最后算出的元素高度是 h*rowHeight 数字
    此方法主要适用于页面布局的需要如果做数据之间的拖动的话并不合适
Logo

前往低代码交流专区

更多推荐