原生拖拽 API 实现拖拽

设置元素 dragable

将元素的 dragable 属性设置 为 true (文本 图片 链接 的draggable 属性默认为 true)则元素可拖放

<div :draggable="true">拖拽</div>

拖放事件

在拖放的过程中涉及到两种元素,一种是被拖拽元素(源对象),一种是放置区元素(目标对象),不同的对象有不同的拖放事件。

触发对象 事件名称 说明
源对象 dragstart 源对象开始被拖动时触发
drag 源对象被拖动过程中反复触发
dragend 源对象拖动结束时触发
目标对象 dragenter 源对象开始进入目标对象范围内触发 使用 pereventDefault 来阻止浏览器默认的拒绝拖拽
dragover 源对象在目标对象范围内移动时触发 使用 pereventDefault 来阻止浏览器默认的拒绝拖拽
dragleave 源对象离开目标对象范围时触发
drop 源对象在目标对象范围内被释放时触发

dragenterdragover事件的默认行为是拒绝接受任何被拖放的元素。因此,我们要在这两个拖放事件中使用preventDefault来阻止浏览器的默认行为;而且目标对象想要变成可释放区域,必须设置dragoverdrop 事件处理程序属性。

拖拽排序

利用拖放API来实现列表的拖拽排序

  1. 由于拖动是实时的,所以没有使用drop而是使用了dragenter触发排序。
  2. 在源对象开始被拖拽时记录其索引dragIndex,当它进入目标对象时(对应dragenter事件),将其插入到目标对象的位置。
  3. 其中dragenter方法中有一个判断this.dragIndex !== index(index为当前目标对象的索引),这是因为源对象同时也是目标对象,当没有这个判断时,源对象开始被拖拽时就会立刻触发自身的dragenter事件,这是不合理的。

拖拽API + 防抖实现

<template><transition-group class="list"><ul@dragstart="dragstart(index)"@dragenter="dragenter($event, index)"@dragover="dragover($event, index)"draggable= "true"v-for="(item, index) in list":key="item.label"class="list-item">{{item.label}}</ul></transition-group>
</template><script>
export default {data() {return {list: [{ label: '列表1' },{ label: '列表2' },{ label: '列表3' },{ label: '列表4' },{ label: '列表5' },{ label: '列表6' },],// 源对象的下标dragIndex: '',// 目标对象的下标enterIndex: '',timeout: null,}},destroyed() {// 每次离开当前界面时,清除定时器clearInterval(this.timeout)this.timeout = null},methods: {dragstart(index) {console.log('start index ===>>> ',index)this.dragIndex = index},// dragenter 和 dragover 事件的默认行为是拒绝接受任何被拖放的元素。 // 因此,我们要在这两个拖放事件中使用`preventDefault`来阻止浏览器的默认行为dragenter(e,index) {  e.preventDefault();this.enterIndex = indexif( this.timeout !== null) {clearTimeout(this.timeout)}// 拖拽事件的防抖this.timeout = setTimeout(() => {if( this.dragIndex !== index){const source = this.list[this.dragIndex]this.list.splice(this.dragIndex,1)this.list.splice(index, 0 , source )// 排序变化后目标对象的索引变成源对象的索引this.dragIndex = index;}}, 100);},dragover(e, index) {e.preventDefault();}},
}
</script><style lang='scss' scoped>
.list {list-style: none;.list-item {// 设置 动画效果transition: transform .3s;cursor: move;width: 300px;background: #EA6E59;border-radius: 4px;color: #FFF;margin-bottom: 6px;height: 50px;line-height: 50px;text-align: center;}
}
</style>

vue awe-dnd 拖拽组件

安装 awe-dnd 组件库

yarn add awe-dnd -S

在 main.js 中将 awe 挂载到全局

// 引入拖拽排序插件
import VueDND from 'awe-dnd'Vue.use(VueDND)

实现案例

<template><div class="title-list"><divv-dragging="{item: item, list:list}"v-for="item in list":key="item.id"class="title-item"><div class="title-child"><span>{{item.id +"--"+ item.name }}</span></div></div></div>
</template>
<script>
export default {name: "titleList",data() {return {list: [{id:1,name:"这是第一个标题名称"},{id:2,name:"这是第二个标题名称"},{id:3,name:"这是第三个标题名称"},{id:4,name:"这是第四个标题名称"},{id:5,name:"这是第五个标题名称"},],};},mounted() {// 拖拽事件this.$dragging.$on("dragged", (result) => {// 将排序后的结果重新赋值this.list = result.value.list;});},
};
</script><style lang="scss" scoped>.title-list {width: 350px;background:#fff;margin:100px auto 0;border: 1px solid red;.title-item {width: 350px;cursor: pointer;border: 1px solid #ededed;.title-child {width: 330px;height: 60px;margin: 0 auto;position: relative;span {width: 100%;font-size: 14px;color: red;  line-height: 30px;// 只显示两行,多余的以省略号显示white-space: normal;overflow: hidden;text-overflow: ellipsis;display: -webkit-box;-webkit-line-clamp: 2;-webkit-box-orient: vertical;// 无论一行还是两行均居中显示position: absolute;left: 0;top: 50%;transform: translate(0, -50%);}}}}
</style>

v-dragging=“{ item: item, list: colors, group: ‘item’,otherData:‘whatever u want’, comb: ‘isComb’}”

list: 列表的遍历数据,

item: 是当前循环值 , 遍历后需要拖拽功能的元素

group: “unique key of dragable list”即拖拽列表的独特key值

// 拖拽事件
this.$dragging.$on("dragged", (result) => {debugger  // console.log('result===>',result)// result 拖拽后的信息  将排序后console.log的结果重新赋值this.list = result.value.list;
});

项目中-- 拖拽的效果 不理想

功能能够实现,但拖拽的效果不是很好,无法修改拖拽图层的透明度

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q0dnwNNC-1655985505378)(C:\Users\Administrator\Desktop\markDown\svg\vue-awe-dnd.gif)]

vue-smooth-DnD

Vue Smooth DnD 是一个快速、轻量级的拖放、可排序的 Vue.js 库,封装了 smooth-dnd 库。

vue-smooth-DnD 文档 : https://github.com/kutlugsahin/vue-smooth-dnd

安装 smooth-dnd

yarn add vue-smooth-dnd -S

API: container

属性 类型 默认值 描述
:orientation string vertical 容器的方向,可以为 horizontal 或 vertical
:behaviour string move 描述被拖动的元素被移动或复制到目标容器。
可以为 move (容器间相互移动) 或 copy(将元素复制到其他容器,但本容器内元素不变) 或 drop-zone(在容器间移动,但是容器内元素的顺序是固定的) 或 contain (只能在容器内移动。)
:tag string, NodeDescription div 容器的元素标签,默认是 div ,可以是字符串如 tag=“table” 也可以是包含 value和 props 属性的对象
:tag=“{value: ‘table’, props: {class: ‘my-table’}}”
:group-name string undefined 可拖动元素可以在具有相同组名的容器之间移动。如果未设置组名容器将不接受来自外部的元素。 这种行为可以被 shouldAcceptDrop 函数覆盖。
:lock-axis string undefined 锁定拖动的移动轴。可用值 x, y 或 undefined。
:drag-handle-selector string undefined 用于指定可以开启拖拽的 CSS 选择器,如果不指定的话则元素内部任意位置都可抓取。
例如 drag-handle-selector=“.column-drag-handle”
:non-drag-area-selector string undefined 禁止拖动的 CSS 选择器,优先于 dragHandleSelector.
:drag-begin-delay number 0(触控设备为 200) 单位毫秒。表示点击元素持续多久后可以开始拖动。在此之前移动光标超过 5px 将取消拖动。
:animation-duration number 250 单位毫秒。表示放置元素和重新排序的动画持续时间。
:auto-scroll-enabled boolean true 如果拖动项目接近边界,第一个可滚动父项将自动滚动
:drag-class string undefined 元素被拖动中的添加的类(不会影响拖拽结束后元素的显示)
:drop-class string undefined 从拖拽元素被放置到被添加到页面过程中添加的类。
:remove-on-drop-out boolean undefined 如果设置为 true,在被拖拽元素没有被放置到任何相关容器时,使用元素索引作为 removedIndex 调用 onDrop()
:drop-placeholder boolean,object undefined 占位符的选项。包含 className, animationDuration, showOnTop 例如
dropPlaceholderOptions: {
className: “drop-preview”,
animationDuration: “150”,
showOnTop: true,
},

Container 属性的使用

<Container
group-name="col"
@drop="(e) => onCardDrop(column.id, e)"
:get-child-payload="getCardPayload(column.id)"
drag-class="card-ghost"
drop-class="card-ghost-drop"
:drop-placeholder="dropPlaceholderOptions"
class="draggable-container"
><Draggable v-for="task in column.list" :key="task.id"><div class="task-card"><div class="task-title">{{ task.name }}</div><divclass="task-priority":style="{ background: priorityMap[task.priority].color }">{{ priorityMap[task.priority].label }}</div></div></Draggable>
</Container>
data() {/// 拖拽时占位符样式dropPlaceholderOptions: {className: "drop-preview",animationDuration: "150",showOnTop: true,},
}

smooth-dnd 生命周期

一次拖动的生命周期通过一系列回调和事件进行描述和控制,下面以包含 3 个容器的示例为例进行说明

Mouse     Calls  Callback / Event       Parameters              Notesdown   o                                                        Initial clickmove   o                                                        Initial drag||         get-child-payload()    index                   Function should return payload    // 自定义传给 onDrop() 的payload对象。||   3 x   should-accept-drop()   srcOptions, payload     Fired for all containers  // 用来确定容器是否可被放置,会覆盖group-name属性。||   3 x   drag-start             dragResult              Fired for all containers||         drag-entervmove   o                                                        Drag over containers||   n x   drag-leave                                     Fired as draggable leaves container|   n x   drag-enter                                     Fired as draggable enters containervup     o                                                        Finish dragshould-animate-drop()  srcOptions, payload     Fires once for dropped container   // 返回 false 则阻止放置动画 3 x   drag-end               dragResult              Fired for all containersn x   drop                   dropResult              Fired only for droppable containers

在每次拖动开始 (drag-start) 之前和每次拖动结束 (drag-end)之前触发should-accept-drop。

dragResult 参数配置 来源于 事件对象

(在事件处理函数中,可以传递一个参数e,这个参数我们叫做事件对象,也叫事件参数。事件对象e是系统传递过去,事件函数也是系统调用的。系统调用事件函数的时候,会给事件函数传递一个参数,传递的参数具有具体值,可以在事件函数执行时获取e中携带的值。)

drag-start 中的 dragResult 参数格式

dragResult: {payload,        // 负载 可以理解为用来记录被拖动的对象isSource,       // 是否是被拖动的容器本身willAcceptDrop, // 是否可以被放置
}

drag-end 中的 dragResult 参数格式


dragResult: {addedIndex,     // 被放置的新添加元素的下标,没有则为 nullremovedIndex,   // 将被移除的元素下标,没有则为 nullpayload,        // 拖动的元素对象,可通过 getChildPayload 指定droppedElement, // 放置的 DOM 元素
}

回调

回调在用户交互之前和期间提供了额外的逻辑和检查。

  • get-child-payload(index)

    自定义传给 onDrop() 的 payload 对象。

    <Container :get-child-payload="getChildPayload">getChildPayload (index) {return {// generate custom payload data here}
    }
    
  • should-accept-drop(sourceContainerOptions, payload)

    在开始拖放之前,所有容器都要调用的函数用来确定容器是否可被放置,会覆盖 group-name 属性。

    <Container :should-accept-drop="shouldAcceptDrop">shouldAcceptDrop (sourceContainerOptions, payload) {return true;
    }
    
  • should-animate-drop(sourceContainerOptions, payload) 返回 false 则阻止放置动画。

    <Container :should-animate-drop="shouldAnimateDrop">shouldAnimateDrop (sourceContainerOptions, payload) {return false;
    }
    
  • get-ghost-parent() 返回幽灵元素(拖动时显示的元素)应该添加到的元素,默认是父元素,某些情况定位会出现问题,则可以选择自定义,如返回 document.body。

    <Container :get-ghost-parent="getGhostParent">getGhostParent() {// i.e return document.body;
    }
    

事件

  • @drag-start 在拖动开始时由所有容器发出的事件。参数 dragResult。

    <Container @drag-start="onDragStart">onDragStart (dragResult) {const { isSource, payload, willAcceptDrop } = dragResult
    }
    
  • @drag-end 所有容器在拖动结束时调用的函数。 在 @drop 事件之前调用。参数 dragResult。

  • @drag-enter 每当拖动的项目在拖动时进入其边界时,相关容器要发出的事件。

  • @drag-leave 每当拖动的项目在拖动时离开其边界时,相关容器要发出的事件。

  • @drop-ready 当容器中可能放置位置的索引发生变化时,被拖动的容器将调用的函数。基本上,每次容器中的可拖动对象滑动以打开拖动项目的空间时都会调用它。参数 dropResult。

  • @drop 放置结束时所有相关容器会发出的事件(放置动画结束后)。源容器和任何可以接受放置的容器都被认为是相关的。参数 dropResult。


API: Draggable

Draggable 容器子组件的包装器。每个子元素都应该用可拖动组件包装。

tag
同容器的 tag 指定可拖拽元素的 DOM 元素标签。 标记名称或节点定义来呈现Draggable的根元素。默认值为’div’。

<Draggable v-for="column in taskColumnList" :key="column.name" :tag="{value: 'tr', props: {class: 'my-table-row'}}">
</Draggable>// --------------或者-----------------<Draggable v-for="column in taskColumnList" :key="column.name" tag="tr">
</Draggable>

效果实现

Vue Smooth DnD 主要包含了两个组件,Container 和 Draggable,Container 包含可拖动的元素或组件,它的每一个子元素都应该被 Draggable 包裹。
每一个要被设置为可拖动的元素都需要被 Draggable 包裹

<template><div><div class="simple-page"><Container @drop="onDrop"><Draggable v-for="item in items" :key="item.id"><div class="draggable-item">{{ item.data }}</div></Draggable></Container></div></div>
</template><script>
import { Container, Draggable } from "vue-smooth-dnd";const applyDrag = (arr, dragResult) => {const { removedIndex, addedIndex, payload } = dragResult;console.log(removedIndex, addedIndex, payload);if (removedIndex === null && addedIndex === null) return arr;const result = [...arr];let itemToAdd = payload;if (removedIndex !== null) {itemToAdd = result.splice(removedIndex, 1)[0];}if (addedIndex !== null) {result.splice(addedIndex, 0, itemToAdd);}return result;
};const generateItems = (count, creator) => {const result = [];for (let i = 0; i < count; i++) {result.push(creator(i));}return result;
};export default {name: "Simple",components: { Container, Draggable },data() {return {items: generateItems(50, (i) => ({ id: i, data: "Draggable " + i })),};},methods: {onDrop(dropResult) {this.items = applyDrag(this.items, dropResult);},},
};
</script><style>
.draggable-item {height: 50px;line-height: 50px;text-align: center;display: block;background-color: #fff;outline: 0;border: 1px solid rgba(0, 0, 0, 0.125);margin-bottom: 2px;margin-top: 2px;cursor: default;user-select: none;
}
</style>

项目中实现 – 拖拽位置无法确定

smooth 的 :orientation 属性限制了容器拖拽的方式,占位为一行默认为 vertical ,默认占位容器的一行

vuedraggable

安装

yarn add vuedraggable

引入

import draggable from 'vuedraggable'

demo

<template><div class="app-container"><div :class="canEdit? 'dargBtn-lock el-icon-unlock': 'dargBtn-lock el-icon-lock' " @click="removeEvent()">{{canEdit? '调整':'锁定'}}</div><ul class="projset-content"><draggable:forceFallback="true":move="onMove":list="imgList"handle=".dargBtn":animation="1000"filter=".undraggable"fallbackClass="fallbackStyle"ghostClass="item_ghost"chosenClass="chosenStyle"dragClass="dragStyle"><li v-for="(item, index) in imgList" :key="index" :class="canEdit ? 'draggable' : 'undraggable'"><div class="dargBtn"><svg-icon icon-class="drag" /></div><img :src="item.path" alt=""><span>{{item.name}}</span></li></draggable></ul></div>
</template><script>import draggable from 'vuedraggable';export default {components: { draggable},data(){return{canEdit:true,imgList: [{path: 'https://lupic.cdn.bcebos.com/20210629/3000005161_14.jpg',name: '1',},{path: 'https://lupic.cdn.bcebos.com/20210629/26202931_14.jpg',name: '2',},{path: 'https://lupic.cdn.bcebos.com/20210629/27788166_14.jpg',name: '3',}]}},created() {},mounted(){},methods:{onMove(relatedContext, draggedContext){console.log(relatedContext.relatedContext.list);},removeEvent (item) {if(this.canEdit){this.canEdit = false;}else{this.canEdit = true;}console.log(this.canEdit);}}}
</script><style scoped lang="scss">.app-container{background: #ffffff;height: 100%;.dargBtn-lock{margin: 0px 50px;color: #2ea9df;}.dragStyle {padding: 10px;border-radius: 4px;opacity: 1;}.fallbackStyle{padding: 10px;border-radius: 4px;opacity: 1;}.chosenStyle {padding: 10px;border-radius: 4px;opacity: 1 !important;}.item_ghost {opacity: 0 !important;}.projset-content{list-style-type: none;position: relative;li{display: inline-block;margin: 10px;}img{width: 141px;height: 100px;}span{justify-content: center;display: flex;}.dargBtn{position: absolute;line-height: 100px;text-align: center;width: 141px;height: 100px;display: none;color: white;// background: rgba(101, 101, 101, 0.6);}.draggable{cursor: pointer;width: 141px;height: 100px;}.draggable:hover .dargBtn{display: block;}}}
</style>

参数说明

参数 类型 说明
group String/ Array group=“name” 用于分组, 同一组的不同list可以相互拖动
list Array 设置拖拽元素
sort Boolean :sort=“true” 是否开启内部排序, 如果设为 false 则它所在的组无法排序
delay Number :delay=“0” 鼠标选中后可以开始拖拽的延迟时间
touchStartThreshold Number :touchStartThreshold=“5” 鼠标移动多少px才可以拖动元素
disabled Boolean :disabled=“true” 是否启用拖拽组件
animation Number :animation="1000"单位 ms 拖动时过渡动画效果
handle Selector handle=“.card-title” 拖动手柄,鼠标移动到 css 名为 card-title 的选择器时才能成为拖动手柄进行拖动
filter Selector filter=“.unmover” 通过选择器设置哪些样式的元素不能被拖动 多个选择器用 ‘,’ 分隔
preventOnFilter Boolean :preventOnFilter="true"默认触发 当拖动filter时是否触发 event.preventDefault()
draggable Selector draggable=“.item” 哪些元素时可以进行拖动的
ghostClass ghostClass=“ghost-style” 设置拖拽元素的占位符样式 模拟被拖动元素的排序情况,自定义样式可能需要添加 !important 才能生效(forceFallback 属性设置味 true)
chosenClass chosenClass=“chosen-style” 设置目标被选中时的样式(包括拖拽时鼠标附着的样式)自定义样式可能需要添加 !important 才能生效(forceFallback 属性设置味 true)
dragClass dragClass=“drag-style” 拖动元素过程中添加的样式,自定义样式可能需要添加 !important 才能生效(forceFallback 属性设置味 true)
dataIdAttr Selector dataIdAttr=”data-id“ 不太清楚
forceFallback forceFallback=“true” 默认为false 设为 true 时将不使用原生的html5 的拖放,可修改拖放过程中的样式
fallbackClass fallback-class=“dragging_style” forceFallback=“true” 时,克隆出新的DOM元素类名,可修改拖放过程中鼠标附着的样式
allbackOnBody Boolean 默认为false allbackOnBody=“true” 时将克隆的元素添加到文档的body中
fallbackTolerance Number 单位 px 拖拽之前应该移动的距离
scroll Boolean 默认为true 当排序的容器是个可滚动的区域,拖放是否能引起区域滚动
scrollFn Function 滚动回调函数,用于自定义滚动条的适配
scrollSensitivity Number 默认30 距离滚动区域多远时滚动条滚动,鼠标靠近边缘多远时开始滚动
scorllSpeed Number 滚动速度

事件

参数 说明 回调参数
start 开始拖动时 function({ to, from, item, clone, oldIndex, newIndex })
add 往列表中移入(添加)单元时 function({ to, from, item, clone, oldIndex, newIndex })
remove 单元被移动到另一个列表(从当前的列表移处)时 function({ to, from, item, clone, oldIndex, newIndex })
update 排序发生变化时 function({ to, from, item, clone, oldIndex, newIndex })
end 拖拽结束时 function({ to, from, item, clone, oldIndex, newIndex })
choose 选择单元格时 function({ to, from, item, clone, oldIndex, newIndex })
sort 排序发生变化时 function({ to, from, item, clone, oldIndex, newIndex })
filter 尝试选择一个被filter过滤的单元时 function({ to, from, item, clone, oldIndex, newIndex })
clone clone 复制出单元格时触发 function({ to, from, item, clone, oldIndex, newIndex })

最佳实践

  <transition><draggable:delay="300":fallback-tolerance="0":list="dragList":force-fallback="true"fallback-class="dragging_style"handle=".card-title"drag-class="drag-style"ghost-class="ghost-style"chosen-class="chosen-style"@update="handleUpdateDrag"class="home-drag-wrapper"><div v-for=" item in dragList" :key="item.id" :class="item.className" class="home-part"><component :is="item.name" :ref="item.name" class="drag-handle " :class=" item.id !== 1? (item.id !== 2? 'card': ''):''">              </component></div></draggable></transition>
.ghost-style {opacity: 0;cursor: grabbing !important;
}
.chosen-style {background-color: rgba(242, 245, 250, .5);border-radius: 8px;z-index: 1000;box-shadow: 0px 3px 28px #BAC4D4;cursor: grabbing !important;}
.dragging-style {border: 1px solid yellow;
}
.drag-style {background-color: rgba(242, 245, 250, .5);border-radius: 8px;z-index: 1000;box-shadow: 0px 3px 28px #BAC4D4;opacity: 1 !important;
}

ghost-class 为排序中的占位样式。

chosen-class 占位符、拖动过程中鼠标附着的副本样式的共同样式。

设置 :force-fallback=“true” 可修改拖放过程中的样式

fallback-class 设置鼠标附着的副本样式, 通过 !important 提升样式优先级。

drag-class 拖拽过程中的样式(鼠标附着样式 opacity: 1 !important; 设置副本的透明度)。

在拖拽过程中配置的类名作用的相应区域:

总结

通过试用多个不同的组件库比较总结,最后在项目中采用vuedraggable,因为该组件的实现方式简单,并且能够灵活控制拖拽的样式,达到目前项目需要的实现效果。

参考

smooth- dnd 参考自 : https://blog.51cto.com/u_15127632/4038149
vuedraggable 参考自:https://blog.csdn.net/Kiruthika/article/details/123903706

vue中实现拖拽排序相关推荐

  1. html5 list 拖拽排序,vue实现可拖拽排序的列表

    在做友情链接管理功能的时候,考虑到有个对友情链接排序的需求,开始的时候 我是在这个list 里边加了rank字段,用户需要手动输入rank ,点击保存后,后台通过用户输入的rank序号进行排序,这显然 ...

  2. Vue + Element 表格拖拽排序、树形表格拖拽排序

    今天给大家分享一下表格(列表)及树形表格拖拽排序,树形表格排序的教程不多,可能还会有问题,我在这里详细给大家讲解一下,如果你有这样的需求或觉得有用,请给个关注或收藏一下吧,方便后期查看使用. 安装so ...

  3. 基于Vue实现表格拖拽排序——sortablejs

    表格拖拽排序 1.安装插件 2.页面引入sortablejs 3.准备表格渲染所需的数据 4.绘制表格结构(要绑定唯一的值row-key,不然会出错) 5.完成表格行与列的拖拽排序事件 1.安装插件 ...

  4. vuedraggable自由拖拽html,vue中draggable拖拽列表的使用

    1.安装 npm install vuedraggable 或者使用镜像安装 cnpm install vuedraggable 2.使用 首先在使用的组件中引入 import draggable f ...

  5. vue中实现拖拽调整顺序功能

    一.使用vuedraggable是标准的组件式封装 或 vue-dragging 指令方式 实现拖拽调整顺序功能. 1:安装依赖 npm install vuedraggable或yarn add v ...

  6. 如何在vue中实现拖拽功能

    HTML5 drag & drop 拖拽与拖放 想要实现该功能,先了解一下H5中的drag和drop这2个概念.

  7. vue中实现拖拽功能

    自定义的全局指令 提示:拖拽指令 文章目录 自定义的全局指令 一.拖拽 1.自定义拖拽指令 2.页面挂载 3.css样式 提示:以下是本篇文章正文内容,下面案例可供参考 一.拖拽 1.自定义拖拽指令 ...

  8. Vue中实现拖拽效果

    Vue2项目中遇到需求要求页面左侧部分实现拖拽效果 实现效果: 1665739151500 实现代码: 一.使用盒子包裹需要拖拽的区域,并绑定ref 二.使用$ref获取DOM信息 具体代码(这个方法 ...

  9. vue中使用拖拽drag

    被拖拽的节点 dragable="true" @dragstart="drag" 拖入的节点 @drop="drop" @dragover= ...

最新文章

  1. ural 1113,jeep problem
  2. Scikit Learn: 在python中机器学习
  3. 如何让编码更加的标准
  4. 无电池摄像头如何实现高清晰度视频编码?
  5. 本地仓库推送到远程仓库:fatal: refusing to merge unrelated histories
  6. 字符串匹配之KMP算法
  7. (待解决!)jmx在PetClinic中的应用
  8. python编程(supervisor程序管理)
  9. JAVA刻度_java – 对数轴标签/刻度定制
  10. 基于ARM的非特定人语音识别系统设计
  11. 简单算法系列之完数的计算
  12. 京瓷m1025维修模式进不去_多个品牌复印机进入维修模式步骤大全
  13. VC知识库的5周年精华珍藏版光盘
  14. 2014Esri全球用户大会——亮点系列之精彩应用案例
  15. 压缩base64图片大小
  16. MP4视频播放问题(有声音无图像)分析与解决——FFmpeg视频处理教程
  17. 基于uniapp的个人课程表
  18. 安卓zip解压软件_手机压缩软件ZArchiver下载、使用教程丨免费、中文,支持7z、zip、rar等所有格式...
  19. 路由器的类型及衡量路由器性能的主要参数指标
  20. 什么是sku转载网上,备忘一个业务知识

热门文章

  1. 使用ECharts实现数据图表分析
  2. X86/X64平台的内存条测试软件介绍(三)
  3. 兰亭集势:颠覆福特生产模式的电子商务公司
  4. 如何远程连接另一台电脑上的打印机~亲测
  5. C# Minitab Box-Cox 最优Lambda λ
  6. ADB+Xshell的使用
  7. 项目一 家庭记账软件
  8. Mac平台retina高分屏开发技术分享
  9. 永恒之塔鲁迪纳6人本守护星各阶段技能
  10. 建库语句 oracle,Oracle数据导入导出和建库语句