马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
源文档:sortablejs - npm
安装
- npm install sortablejs --save
复制代码 引入项目
- import Sortable from 'sortablejs';
复制代码 利用示例
- <template>
- <ul id="items">
- <li>item 1</li>
- <li>item 2</li>
- <li>item 3</li>
- </ul>
- </template>
- <script setup>
- import Sortable from 'sortablejs';
- const el = document.getElementById('items');
- const sortable = Sortable.create(el);
- </script>
- <style scoped lang="scss">
- </style>
复制代码 sortablejs的配置项
- const sortable = new Sortable(el, {
- group: "name", // or { name: "...", pull: [true, false, 'clone', array], put: [true, false, array] }
- sort: true, //是否可以在列表内排序,默认开启
- delay: 0, //拖拽延迟时间(通常用于移动端实现长按拖拽)
- delayOnTouchOnly: false, //只有当用户使用触摸时才会延迟
- touchStartThreshold: 0, // 在取消延迟拖动事件之前,应该移动多少像素(px)
- disabled: false, //如果设置为true,则禁用可排序。
- store: null, // @see Store
- animation: 150, // ms,排序时移动项目的动画速度,设置0则无过渡动画
- easing: "cubic-bezier(1, 0, 0, 1)", //渐变动画,默认为null,可访问https://easings.net/查看示例
- handle: ".my-handle", // 需要绑定的元素(比如我们想长按某个盒子来拖拽其父元素,那么此时我们仅需要给这个盒子添加这里配置的类型即可)
- filter: ".ignore-elements", //不需要进行拖动的元素(给元素添加这个选项配置的类名后,该元素将不会被拖动)
- preventOnFilter: true, // 当触发filter时调用event.preventDefault()
- draggable: ".item", // 指定元素内的哪些项可以被拖动
- dataIdAttr: 'data-id', // HTML attribute that is used by the `toArray()` method
- ghostClass: "sortable-ghost", //占位元素类名,可以对此类名进行配置以实现特定效果(拖拽时,sortablejs会生成一个占位元素占据元素的位置,此类名主要用于控制这个元素的样式)
- chosenClass: "sortable-chosen", //所选项目的类名
- dragClass: "sortable-drag", //拖动项的类名
- swapThreshold: 1, //交换区阈值
- invertSwap: false, //如果设置为true,将始终使用反向交换区
- invertedSwapThreshold: 1, //反转交换区的阈值(默认设置为swapThreshold值)
- direction: 'horizontal', // 可分拣方向(如果没有给出,将自动检测)
- forceFallback: false, //忽略HTML5 行为并强制回退
- fallbackClass: "sortable-fallback", //使用forceFallback时克隆的DOM元素的类名
- fallbackOnBody: false, //将克隆的DOM元素附加到文档正文中
- fallbackTolerance: 0, //以像素为单位指定鼠标在被视为拖动之前应该移动多远。
- dragoverBubble: false,//拖拽经过时是否冒泡
- removeCloneOnHide: true, //当clone元素未显示时将其删除,而不是将其隐藏
- emptyInsertThreshold: 5, //px,鼠标距离必须为空可排序,才能将拖动元素插入其中
- setData: function (/** DataTransfer */dataTransfer, /** HTMLElement*/dragEl) {
- dataTransfer.setData('Text', dragEl.textContent); //HTML5 DragEvent的DataTransfer对象
- },
- //元素被选中时触发
- onChoose: function (/**Event*/evt) {
- evt.oldIndex; //当前元素在父元素中的索引
- },
- //元素未被选中时(与onEnd事件相似)
- onUnchoose: function(/**Event*/evt) {
- // same properties as onEnd
- },
- //开始拖拽时
- onStart: function (/**Event*/evt) {
- evt.oldIndex; //当前元素在父元素中的索引
- },
- //拖拽完成时
- onEnd: function (/**Event*/evt) {
- var itemEl = evt.item; //被拖拽的元素
- evt.to; //目标列表
- evt.from; //初始列表
- evt.oldIndex; //初始列表的初始索引(即拖拽改变之前的列表索引)
- evt.newIndex; //元素在新父级中的新索引(即拖拽之后形成的列表的索引)
- evt.oldDraggableIndex; //元素在旧父元素内的旧索引,仅计算可拖动元素
- evt.newDraggableIndex; //元素在新父级中的新索引,仅计算可拖动元素
- evt.clone //克隆元素
- evt.pullMode; //当项目位于另一个可排序的位置时:如果是克隆,则为“clone”;如果是移
- 动,则为true
- //元素从另一个列表中删除到列表中
- onAdd: function (/**Event*/evt) {
- //与onEnd具有相同的属性
- },
- //更改列表中的排序
- onUpdate: function (/**Event*/evt) {
- //与onEnd具有相同的属性
- },
- //由列表的任何更改调用(添加/更新/删除)
- onSort: function (/**Event*/evt) {
- //与onEnd具有相同的属性
- },
- //元素从列表中删除到另一个列表中
- onRemove: function (/**Event*/evt) {
- //与onEnd具有相同的属性
- },
- //尝试拖动已过滤的元素
- onFilter: function (/**Event*/evt) {
- var itemEl = evt.item; //HTMLElement接收到“mousedown”、“tapstart”事件。
- },
- //在列表中或列表之间移动项目的事件
- onMove: function (/**Event*/evt, /**Event*/originalEvent) {
- // Example: https://jsbin.com/nawahef/edit?js,output
- evt.dragged; // 被拖动元素
- evt.draggedRect; // DOMRect {left, top, right, bottom}
- evt.related; // HTMLElement on which have guided
- evt.relatedRect; // DOMRect
- evt.willInsertAfter; //布尔值,默认为真。为真的情况下Sortable将在目标后插入拖动元素
- originalEvent.clientY; //鼠标位置
- // return false; — for cancel
- // return -1; — 在目标之前插入
- // return 1; — 在目标之后插入
- // return true; —根据方向保留默认插入点
- // return void; —根据方向保留默认插入点
- },
- //创建元素克隆时调用
- onClone: function (/**Event*/evt) {
- var origEl = evt.item;
- var cloneEl = evt.clone;
- },
- //当拖动元素改变位置时调用
- onChange: function(/**Event*/evt) {
- evt.newIndex //使用此事件的最可能原因是获取拖动元素的当前索引
- // same properties as onEnd
- }
- });
复制代码 vue3中的利用演示
- <template>
- <div class="home">
- <ul ref="boxRef" >
- <li v-for="item in list" :key="item.id" >
- <div class="bread">
- <van-icon name="wap-nav" size="30px" ></van-icon>
- </div>
- <span> {{ item.text }}</span>
- </li>
- </ul>
- </div>
- </template>
- <script setup>
- import { ref,onMounted } from 'vue';
- import Sortable from 'sortablejs';
- //sortable实例
- const instance = ref(null)
- const list = ref([
- {
- text: '张三',
- id: 1,
- },
- {
- text: '李四',
- id: 2,
- },
- {
- text: '王五',
- id: 3,
- },
- {
- text: '赵四',
- id: 4,
- },
- {
- text: '王大麻子',
- id: 5,
- },
- ]);
- //获取容器dom元素
- const boxRef = ref(null)
- onMounted(()=>{
- instance.value = Sortable.create(boxRef.value,{
- handle:'.bread', //设置了此类名,只有长按有这个类名的元素才能拖动(注意这里要带上选择器符号)
- delay:600, //延迟600毫秒才能拖动
- chosenClass:"move" //可以拖动时,被拖动项的类名
- })
- })
- </script>
- <style scoped lang="less">
- .move{
- background: orange;
- }
- .box {
- margin: 20px auto;
- width: 600px;
- height: 600px;
- box-shadow: 0 0 3px 5px #ccc;
- }
- ul{
- margin:10px auto;
- width:600px;
- li{
- margin:10px 0;
- display: flex;
- align-items: center;
- height:80px;
- line-height: 80px;
- text-align: center;
- background:#ccc;
- .bread{
- margin: 0 20px;
- display: flex;
- align-items: center;
- width:50px;
- height:50px;
- }
- }
- }
- </style>
复制代码 在实际的利用中我们通常利用sortablejs做拖拽排序,这就会涉及到异步请求及请求发送失败的情况。那么就会发现一个题目,当我们的请求发送失败后按照常理应该还原排序但是sortablejs似乎并没有给予相应的方法来实现这个功能。我们可以如下操作:
- <template>
- <div class="home">
- <ul ref="boxRef" @sort="onSort">
- <li v-for="item in list" :key="item.id">
- <div class="bread">
- <van-icon name="wap-nav" size="30px"></van-icon>
- </div>
- <span> {{ item.text }}</span>
- </li>
- </ul>
- </div>
- </template>
- <script setup >
- import { ref, onMounted } from 'vue';
- import Sortable from 'sortablejs';
- //获取容器dom元素
- const boxRef = ref(null);
- const list = ref([
- {
- text: '张三',
- id: 1,
- },
- {
- text: '李四',
- id: 2,
- },
- {
- text: '王五',
- id: 3,
- },
- {
- text: '赵四',
- id: 4,
- },
- {
- text: '王大麻子',
- id: 5,
- },
- ]);
- //sortable实例
- const instance = ref(null);
- //排序时触发的回调函数
- const onSort = async (value) => {
- const { oldIndex, newIndex, from } = value;
- try {
- //模拟的异步请求失败情况
- await new Promise((resolve, reject) => {
- reject(new Error('发送错误'));
- });
- } catch (error) {
- //请求失败时还原排序
- const List = Array.from(from.children);
- const item = List.splice(newIndex, 1)[0];
- if (oldIndex > newIndex) {
- from.insertBefore(item, List[oldIndex + 1]);
- } else {
- from.insertBefore(item, List[oldIndex]);
- }
- }
- };
- onMounted(() => {
- //初始化sortablejs实例
- instance.value = Sortable.create(boxRef.value, {
- handle: '.bread', //设置了此类名,只有长按有这个类名的元素才能拖动(注意这里要带上选择器符号)
- // delay:600, //延迟600毫秒才能拖动
- chosenClass: 'move', //可以拖动时,被拖动项的类名(可以自定义样式)
- });
- });
- </script>
- <style scoped lang="less">
- .move {
- background: orange;
- }
- .box {
- margin: 20px auto;
- width: 600px;
- height: 600px;
- box-shadow: 0 0 3px 5px #ccc;
- }
- ul {
- margin: 10px auto;
- width: 600px;
- li {
- margin: 10px 0;
- display: flex;
- align-items: center;
- height: 80px;
- line-height: 80px;
- text-align: center;
- background: #ccc;
- .bread {
- margin: 0 20px;
- display: flex;
- align-items: center;
- width: 50px;
- height: 50px;
- }
- }
- }
- </style>
复制代码 这样就可以实现一样寻常的工作需求,考虑到每次写这么多东西会很贫苦,我们可以利用vue的自定义指令将它封装成一个指令。现在已经有插件完成了这一步调,各人也可以实验一下这个插件。
传送门:vue3-sortablejs - npm
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |