Vue.Draggable的使用

2023-09-05 16:49 秦倩 16809

Vue.Draggable是一款基于Sortable.js拖拽插件

一、特点

  1. 完全支持Sortable.js的功能支持触摸设备支持拖拽和选择文本智能自动滚动支持在不同列表之间拖拽没有JQuery依赖项
  2. 与视图模型同步刷新
  3. 与Vue2动画兼容
  4. 支持撤销操作
  5. 当需要完全控制时,可抛出所有的变化事件
  6. 与现有的UI组件兼容(比如vuetify、element、vue material等)

二、官方网站

https://github.com/SortableJS/Vue.Draggable

三、props

属性名称 说明
value 实现拖拽的list数组,不能直接使用,只能通过v-model使用,通常与v-for指令所用的数组相同
list 与value功能相同,但不能与v-model共用
tag draggable渲染后在页面中展现出来的HTML节点类型,默认值为‘div’
clone 当返回值为true时,拖拽的元素将被复制。参数为被拖拽的元素,返回值是其克隆版本、
move 如果是空值,则将以类似于Sortable的onMove回调的方式调用此函数,返回false取消拖拽操作
componentData 用来结合UI组件的,可以理解为代理了UI组件的定制信息
options 列表配置项,Vue.Draggable新版本废弃了options属性,建议使用v-bind属性作为配置项

options配置项

四、Events

   

五、slot插槽

Header

使用标题插槽在vuedraggable组件中添加不可拖动的元素。它应该与draggable选项一起使用来标记draggable元素。请注意,无论标题槽在模板中的位置如何,它总是被添加到默认槽之前。

<draggable v-model="myArray" draggable=".item">
    <div v-for="element in myArray" :key="element.id" class="item">
        {{element.name}}
    </div>
    <button slot="header" @click="addPeople">Add</button>
</draggable>

Footer

使用页脚槽在vuedraggable组件中添加不可拖动的元素。它应该与draggable选项一起使用,以标记draggable元素。请注意,无论页脚槽在模板中的位置如何,它都将始终添加到默认槽之后。

<draggable v-model="myArray" draggable=".item">
    <div v-for="element in myArray" :key="element.id" class="item">
        {{element.name}}
    </div>
    <button slot="footer" @click="addPeople">Add</button>
</draggable>

注意:页眉或页脚插槽都不能与 tarnstion-group 一起使用。

六、安装方式

yarn

yarn add vuedraggable

npm

npm install vuedraggable

七、引入

import draggable from 'vuedraggable'
// UMD浏览器直接引用JS方式
<script src="https://www.itxst.com/package/vue/vue.min.js"></script>
<script src="https://www.itxst.com/package/sortable/Sortable.min.js"></script>
<script src="https://www.itxst.com/package/vuedraggable/vuedraggable.umd.min.js"></script>

八、用法

1.单列拖拽

  <div id="app">
    <h3>单列拖拽</h3>
    <draggable 
      v-model="myArray" 
      chosen-class="chosen" 
      force-fallback="true" 
    >
      <transition-group>
        <div class="item" v-for="item in myArray" :key="item.id">{{item.name}}</div>
      </transition-group>
    </draggable>
  </div>

2.多列拖拽

注意,vuedraggable新版本废弃了options属性,建议使用v-bind属性作为配置项

多列拖拽示例代码使用了options属性,控制台抛出警告

北方城市list中增加tag="ul",Elements中可以看到其包裹标签为ul,未加tag属性的南方城市则是默标签div

<body style="padding:10px;">
  <div id="app">
    <h3>多列拖拽</h3>
    <div style="display: flex; width: 300px; justify-content: space-between;">
      <div>
        <h4>北方城市</h4>
        <draggable v-model="arr1" tag="ul" :options="dragOptions">
          <transition-group>
            <div class="item" v-for="item in arr1" :key="item.id">{{item.name}}</div>
          </transition-group>
        </draggable>
      </div>
      <div>
        <h4>南方城市</h4>
        <draggable v-model="arr2" :options="dragOptions">
          <transition-group>
            <div class="item" v-for="item in arr2" :key="item.id">{{item.name}}</div>
          </transition-group>
        </draggable>
      </div>
    </div>
  </div>
  <script>
    // 全局注册组件
    Vue.component('vuedraggable', window.vuedraggable)
    var app = new Vue({
      el: '#app',
      components: {
        vuedraggable: window.vuedraggable,//当前页面注册组件
      },
      data() {
        return {
          dragOptions: {
            group: 'city', //group相同时不同的list之间了可以拖动
            animation: '300'
          },
          // dragOptions1: {
          //   group: 'citys', //group不同时不同的list之间了不可拖动
          //   animation: '300'
          // },
          arr1: [{id: 1, name: '哈尔滨'},{id: 2, name: '吉林'},{id: 3, name: '长春'},{id: 4, name: '大连'}],
          arr2: [{id: 1, name: '贵州'},{id: 2, name: '昆明'},{id: 3, name: '北流'},{id: 4, name: '毕节'}],
        };
      }
    });
  </script>
</body>

3.clone、move

clone: :options="{group:{name: 'city',pull:'clone'},sort: true}",表示允许克隆被拖动的元素

move:获取当前拖动元素的对象、控制某个/些元素不允许被拖拽

end:拖拽事件结束,用来判断是否已经存在对象

左侧的draggable标签添加了options配置项(新版本为v-bind)

{group:{name: 'city',pull:'clone'},sort: true}:name与右侧group名称一致,可相互拖拽, pull:‘clone’表示进行克隆拖动操作,sort: true 表示拖动时允许进行排序操作

<body style="padding:10px;">
  <div id="app">
    <h3>clone</h3>
    <div style="display: flex; width: 300px; justify-content: space-between;">
      <draggable v-model="arr1" :options="{group:{name: 'city',pull:'clone'},sort: true}" :move="onMove" @end="end1">
        <transition-group>
          <div class="item" v-for="item in arr1" :key="item.id">{{item.name}}</div>
        </transition-group>
      </draggable>
      <draggable v-model="arr2" group="city" v-bind="dragOptions" @end="end2">
        <transition-group>
          <div class="item" v-for="item in arr2" :key="item.id">{{item.name}}</div>
        </transition-group>
      </draggable>
    </div>
  </div>
  <script>
    // 全局注册组件
    Vue.component('vuedraggable', window.vuedraggable)
    var app = new Vue({
      el: '#app',
      components: {
        vuedraggable: window.vuedraggable,//当前页面注册组件
      },
      data() {
        return {
          dragOptions: {
            animation: '300'
          },
          arr1: [{id: 1, name: '西瓜'},{id: 2, name: '草莓'},{id: 3, name: '葡萄'},{id: 4, name: '榴莲'}],
          arr2: [{id: 11, name: '胡萝卜'},{id: 22, name: '西红柿'}],
        };
      },
      methods: {
        onMove(e,originalEvent) {
          if(e.draggedContext.element.id == 1) return false // 不允许拖拽
          if(e.relatedContext.element.id == 4) return false // 不允许停靠
          return true
        },
        end1(e) {
          console.log(e,'111');
        },
        end2(e) {
          console.log(e,'222');
        }
      }
    });
  </script>
</body>