Vue组件draggable的使用

在vue项目中使用draggable 拖拽组件来拖动排序

正常使用代码如下:
<template>
  <draggable
    v-model="draggableList"
    :tag="tag"
    :scroll="true"
    :filter="filter"
    :move="() => true"
    :animation="animation"
    item-key="id"
    @end="endCallback"
  >
    <!-- 这里是拖拽的内容 -->
    <template #item="{ element }">
      <div class="px-6px cursor-pointer my-6px hover-bg-#f2f2f2" :class="{ filterClass: element.id === 3 }">
        <!-- 坑:拖拽的div css 样式不要为position relative ,否则无法使用 -->
        <span>{{ element.label }}</span>
        <n-icon class="ml-6px text-12px" @click="handleDelete(element.id)">
          <svg
            t="1659758644821"
            class="icon"
            viewBox="0 0 1024 1024"
            version="1.1"
            xmlns="http://www.w3.org/2000/svg"
            p-id="2402"
          >
            <path
              d="M218.496 846.933333a42.666667 42.666667 0 0 1-60.330667-60.373333l272.170667-272.170667L177.066667 261.162667a42.666667 42.666667 0 0 1 60.330666-60.330667l253.226667 253.226667 270.933333-270.933334a42.666667 42.666667 0 0 1 60.288 60.373334l-270.890666 270.933333 289.834666 289.792a42.666667 42.666667 0 1 1-60.330666 60.330667L490.666667 574.762667l-272.170667 272.128z"
              p-id="2403"
            ></path>
          </svg>
        </n-icon>
      </div>
    </template>
  </draggable>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import draggable from 'vuedraggable';

const tag = 'div'; // 拖拽框父盒子会是tbody,写其它标签,如div,则父盒子为div
const filter = '.filterClass'; // 有这个类名则不可拖拽
const animation = 200; // 拖拽变化的时候有个200秒的变化动画
// 拖拽的列表
const draggableList = ref([
  { label: '零--------------零', id: 0 },
  { label: '一--------------一', id: 1 },
  { label: '二--------------二', id: 2 },
  { label: '三---disabledraggable---三', id: 3 },
  { label: '四--------------四', id: 4 },
  { label: '五--------------五', id: 5 },
  { label: '六--------------六', id: 6 }
]);

function endCallback(e: { newIndex: number; oldIndex: number }) {
  // 穿梭框拖动会自动改变位置,如果想手动改变,可以这样,将新的位置和旧的位置进行替换
  // const { newIndex, oldIndex } = e;
  // const tempIndex = draggableList.value.splice(oldIndex, 1)[0];
  // draggableList.value.splice(newIndex, 0, tempIndex);
}

// 移除拖拽项
function handleDelete(id: string) {
  const index = draggableList.value.find(item => item.id === id);
  draggableList.value.splice(index, 1);
}
</script>

上面要注意可能会踩的两个坑

1. 拖拽数据移动顺序错乱,可能是因为绑定的列表,在拖拽完成之后,被其它函数改变了,可以在end 函数里面打断点排查

2.每行数据的值的外层元素不能设置position为relative,否则会出现无法拖动的情况

使用 h 函数如下

html:

<render-draggable />

js:


const renderDraggable = h(
  draggable,
  {
    class: 'px-4px',
    scroll: true,
    itemKey: 'id',
    tag,
    filter,
    modelValue: draggableList.value,
    move: () => {
      return true;
    },
    onEnd: endCallback
  },
  {
    item: ({ element }: { element: IProjectItem }) => {
      return h(
        'div',
        {
          class: `px-6px cursor-pointer my-6px hover-bg-#f2f2f2 ${element.id === 3 ? 'filterClass' : ''}`
        },
        {
          default: () => {
            return [
              h('span', {}, element.label),
              h(
                NIcon,
                { class: 'ml-6px text-12px' },
                {
                  default: () =>
                    h(
                      'svg',
                      {
                        t: '1659758644821',
                        class: 'icon',
                        viewBox: '0 0 1024 1024',
                        version: '1.1',
                        xmlns: 'http://www.w3.org/2000/svg',
                        pId: '2402'
                      },
                      {
                        default: () =>
                          h('path', {
                            d: 'M218.496 846.933333a42.666667 42.666667 0 0 1-60.330667-60.373333l272.170667-272.170667L177.066667 261.162667a42.666667 42.666667 0 0 1 60.330666-60.330667l253.226667 253.226667 270.933333-270.933334a42.666667 42.666667 0 0 1 60.288 60.373334l-270.890666 270.933333 289.834666 289.792a42.666667 42.666667 0 1 1-60.330666 60.330667L490.666667 574.762667l-272.170667 272.128z',
                            pId: '2403'
                          })
                      }
                    )
                }
              )
            ];
          }
        }
      );
    }
  }
);


function endCallback(e: { newIndex: number; oldIndex: number }) {
  // 穿梭框拖动会自动改变位置,如果想手动改变,可以这样,将新的位置和旧的位置进行替换
  const { newIndex, oldIndex } = e;
  const tempIndex = draggableList.value.splice(oldIndex, 1)[0];
  draggableList.value.splice(newIndex, 0, tempIndex);
}

更多功能,可看中文文档,可以实现一些复杂的场景,如两个列表之间的拖动、表格的行列拖动等

 有两个版本

1.普通版本 vue.draggable.next 中文文档 - itxst.comvue.draggable.next 是一款vue3的拖拽插件,是vue.draggable升级版本,同样是基于Sortable.js实现的,你可以用它来拖拽列表、菜单、工作台、选项卡等常见的工作场景,本人在工作台和多选项卡环境下实践过,比自己实现的拖拽效果优雅多了。icon-default.png?t=N7T8https://www.itxst.com/vue-draggable-next/tutorial.html

2.plus 版本VueDraggablePlus | 支持 Vue2 和 Vue3 的拖拽组件vue3拖拽排序组件icon-default.png?t=N7T8https://alfred-skyblue.gitee.io/vue-draggable-plus/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值