vue中實現(xiàn)拖拽排序功能的詳細(xì)教程
原生拖拽 API 實現(xiàn)拖拽
設(shè)置元素 dragable
將元素的 dragable 屬性設(shè)置 為 true (文本 圖片 鏈接 的draggable 屬性默認(rèn)為 true)則元素可拖放
<div :draggable="true">拖拽</div>
拖放事件
在拖放的過程中涉及到兩種元素,一種是被拖拽元素(源對象),一種是放置區(qū)元素(目標(biāo)對象),不同的對象有不同的拖放事件。
觸發(fā)對象 | 事件名稱 | 說明 |
---|---|---|
源對象 | dragstart | 源對象開始被拖動時觸發(fā) |
drag | 源對象被拖動過程中反復(fù)觸發(fā) | |
dragend | 源對象拖動結(jié)束時觸發(fā) | |
目標(biāo)對象 | dragenter | 源對象開始進(jìn)入目標(biāo)對象范圍內(nèi)觸發(fā) 使用 pereventDefault 來阻止瀏覽器默認(rèn)的拒絕拖拽 |
dragover | 源對象在目標(biāo)對象范圍內(nèi)移動時觸發(fā) 使用 pereventDefault 來阻止瀏覽器默認(rèn)的拒絕拖拽 | |
dragleave | 源對象離開目標(biāo)對象范圍時觸發(fā) | |
drop | 源對象在目標(biāo)對象范圍內(nèi)被釋放時觸發(fā) |
dragenter
和dragover
事件的默認(rèn)行為是拒絕接受任何被拖放的元素。因此,我們要在這兩個拖放事件中使用preventDefault
來阻止瀏覽器的默認(rèn)行為;而且目標(biāo)對象想要變成可釋放區(qū)域,必須設(shè)置dragover
和drop
事件處理程序?qū)傩浴?/p>
拖拽排序
利用拖放API來實現(xiàn)列表的拖拽排序
- 由于拖動是實時的,所以沒有使用drop而是使用了dragenter觸發(fā)排序。
- 在源對象開始被拖拽時記錄其索引dragIndex,當(dāng)它進(jìn)入目標(biāo)對象時(對應(yīng)dragenter事件),將其插入到目標(biāo)對象的位置。
- 其中dragenter方法中有一個判斷this.dragIndex !== index(index為當(dāng)前目標(biāo)對象的索引),這是因為源對象同時也是目標(biāo)對象,當(dāng)沒有這個判斷時,源對象開始被拖拽時就會立刻觸發(fā)自身的dragenter事件,這是不合理的。
拖拽API + 防抖實現(xiàn)
<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' }, ], // 源對象的下標(biāo) dragIndex: '', // 目標(biāo)對象的下標(biāo) enterIndex: '', timeout: null, } }, destroyed() { // 每次離開當(dāng)前界面時,清除定時器 clearInterval(this.timeout) this.timeout = null }, methods: { dragstart(index) { console.log('start index ===>>> ',index) this.dragIndex = index }, // dragenter 和 dragover 事件的默認(rèn)行為是拒絕接受任何被拖放的元素。 // 因此,我們要在這兩個拖放事件中使用`preventDefault`來阻止瀏覽器的默認(rèn)行為 dragenter(e,index) { e.preventDefault(); this.enterIndex = index if( 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 ) // 排序變化后目標(biāo)對象的索引變成源對象的索引 this.dragIndex = index; } }, 100); }, dragover(e, index) { e.preventDefault(); } }, } </script> <style lang='scss' scoped> .list { list-style: none; .list-item { // 設(shè)置 動畫效果 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)
實現(xiàn)案例
<template> <div class="title-list"> <div v-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:"這是第一個標(biāo)題名稱"}, {id:2,name:"這是第二個標(biāo)題名稱"}, {id:3,name:"這是第三個標(biāo)題名稱"}, {id:4,name:"這是第四個標(biāo)題名稱"}, {id:5,name:"這是第五個標(biāo)題名稱"}, ], }; }, mounted() { // 拖拽事件 this.$dragging.$on("dragged", (result) => { // 將排序后的結(jié)果重新賦值 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: 列表的遍歷數(shù)據(jù),
item: 是當(dāng)前循環(huán)值 , 遍歷后需要拖拽功能的元素
group: “unique key of dragable list”即拖拽列表的獨特key值
// 拖拽事件 this.$dragging.$on("dragged", (result) => { debugger // console.log('result===>',result) // result 拖拽后的信息 將排序后console.log的結(jié)果重新賦值 this.list = result.value.list; });
項目中-- 拖拽的效果 不理想
功能能夠?qū)崿F(xiàn),但拖拽的效果不是很好,無法修改拖拽圖層的透明度
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
屬性 | 類型 | 默認(rèn)值 | 描述 |
---|---|---|---|
:orientation | string | vertical | 容器的方向,可以為 horizontal 或 vertical |
:behaviour | string | move | 描述被拖動的元素被移動或復(fù)制到目標(biāo)容器。 可以為 move (容器間相互移動) 或 copy(將元素復(fù)制到其他容器,但本容器內(nèi)元素不變) 或 drop-zone(在容器間移動,但是容器內(nèi)元素的順序是固定的) 或 contain (只能在容器內(nèi)移動。) |
:tag | string, NodeDescription | div | 容器的元素標(biāo)簽,默認(rèn)是 div ,可以是字符串如 tag=“table” 也可以是包含 value和 props 屬性的對象 :tag=“{value: ‘table’, props: {class: ‘my-table’}}” |
:group-name | string | undefined | 可拖動元素可以在具有相同組名的容器之間移動。如果未設(shè)置組名容器將不接受來自外部的元素。 這種行為可以被 shouldAcceptDrop 函數(shù)覆蓋。 |
:lock-axis | string | undefined | 鎖定拖動的移動軸??捎弥?x, y 或 undefined。 |
:drag-handle-selector | string | undefined | 用于指定可以開啟拖拽的 CSS 選擇器,如果不指定的話則元素內(nèi)部任意位置都可抓取。 例如 drag-handle-selector=“.column-drag-handle” |
:non-drag-area-selector | string | undefined | 禁止拖動的 CSS 選擇器,優(yōu)先于 dragHandleSelector. |
:drag-begin-delay | number | 0(觸控設(shè)備為 200) | 單位毫秒。表示點擊元素持續(xù)多久后可以開始拖動。在此之前移動光標(biāo)超過 5px 將取消拖動。 |
:animation-duration | number | 250 | 單位毫秒。表示放置元素和重新排序的動畫持續(xù)時間。 |
:auto-scroll-enabled | boolean | true | 如果拖動項目接近邊界,第一個可滾動父項將自動滾動 |
:drag-class | string | undefined | 元素被拖動中的添加的類(不會影響拖拽結(jié)束后元素的顯示) |
:drop-class | string | undefined | 從拖拽元素被放置到被添加到頁面過程中添加的類。 |
:remove-on-drop-out | boolean | undefined | 如果設(shè)置為 true,在被拖拽元素沒有被放置到任何相關(guān)容器時,使用元素索引作為 removedIndex 調(diào)用 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> <div class="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 生命周期
一次拖動的生命周期通過一系列回調(diào)和事件進(jìn)行描述和控制,下面以包含 3 個容器的示例為例進(jìn)行說明
Mouse Calls Callback / Event Parameters Notes
down o Initial click
move 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-enter
vmove o Drag over containers
|
| n x drag-leave Fired as draggable leaves container
| n x drag-enter Fired as draggable enters container
vup o Finish drag
should-animate-drop() srcOptions, payload Fires once for dropped container // 返回 false 則阻止放置動畫
3 x drag-end dragResult Fired for all containers
n x drop dropResult Fired only for droppable containers
在每次拖動開始 (drag-start) 之前和每次拖動結(jié)束 (drag-end)之前觸發(fā)should-accept-drop。
dragResult 參數(shù)配置 來源于 事件對象
(在事件處理函數(shù)中,可以傳遞一個參數(shù)e,這個參數(shù)我們叫做事件對象,也叫事件參數(shù)。事件對象e是系統(tǒng)傳遞過去,事件函數(shù)也是系統(tǒng)調(diào)用的。系統(tǒng)調(diào)用事件函數(shù)的時候,會給事件函數(shù)傳遞一個參數(shù),傳遞的參數(shù)具有具體值,可以在事件函數(shù)執(zhí)行時獲取e中攜帶的值。)
drag-start 中的 dragResult 參數(shù)格式
dragResult: { payload, // 負(fù)載 可以理解為用來記錄被拖動的對象 isSource, // 是否是被拖動的容器本身 willAcceptDrop, // 是否可以被放置 }
drag-end 中的 dragResult 參數(shù)格式
dragResult: { addedIndex, // 被放置的新添加元素的下標(biāo),沒有則為 null removedIndex, // 將被移除的元素下標(biāo),沒有則為 null payload, // 拖動的元素對象,可通過 getChildPayload 指定 droppedElement, // 放置的 DOM 元素 }
回調(diào)
回調(diào)在用戶交互之前和期間提供了額外的邏輯和檢查。
- get-child-payload(index)
自定義傳給 onDrop() 的 payload 對象。
<Container :get-child-payload="getChildPayload"> getChildPayload (index) { return { // generate custom payload data here } }
- should-accept-drop(sourceContainerOptions, payload)
在開始拖放之前,所有容器都要調(diào)用的函數(shù)用來確定容器是否可被放置,會覆蓋 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() 返回幽靈元素(拖動時顯示的元素)應(yīng)該添加到的元素,默認(rèn)是父元素,某些情況定位會出現(xiàn)問題,則可以選擇自定義,如返回 document.body。
<Container :get-ghost-parent="getGhostParent"> getGhostParent() { // i.e return document.body; }
事件
- @drag-start 在拖動開始時由所有容器發(fā)出的事件。參數(shù) dragResult。
<Container @drag-start="onDragStart"> onDragStart (dragResult) { const { isSource, payload, willAcceptDrop } = dragResult }
- @drag-end 所有容器在拖動結(jié)束時調(diào)用的函數(shù)。 在 @drop 事件之前調(diào)用。參數(shù) dragResult。
- @drag-enter 每當(dāng)拖動的項目在拖動時進(jìn)入其邊界時,相關(guān)容器要發(fā)出的事件。
- @drag-leave 每當(dāng)拖動的項目在拖動時離開其邊界時,相關(guān)容器要發(fā)出的事件。
- @drop-ready 當(dāng)容器中可能放置位置的索引發(fā)生變化時,被拖動的容器將調(diào)用的函數(shù)?;旧希看稳萜髦械目赏蟿訉ο蠡瑒右源蜷_拖動項目的空間時都會調(diào)用它。參數(shù) dropResult。
- @drop 放置結(jié)束時所有相關(guān)容器會發(fā)出的事件(放置動畫結(jié)束后)。源容器和任何可以接受放置的容器都被認(rèn)為是相關(guān)的。參數(shù) dropResult。
API: Draggable
Draggable 容器子組件的包裝器。每個子元素都應(yīng)該用可拖動組件包裝。
tag
同容器的 tag 指定可拖拽元素的 DOM 元素標(biāo)簽。 標(biāo)記名稱或節(jié)點定義來呈現(xiàn)Draggable的根元素。默認(rèn)值為’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>
效果實現(xiàn)
Vue Smooth DnD 主要包含了兩個組件,Container 和 Draggable,Container 包含可拖動的元素或組件,它的每一個子元素都應(yīng)該被 Draggable 包裹。
每一個要被設(shè)置為可拖動的元素都需要被 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>
項目中實現(xiàn) – 拖拽位置無法確定
smooth 的 :orientation 屬性限制了容器拖拽的方式,占位為一行默認(rèn)為 vertical ,默認(rèn)占位容器的一行
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? '調(diào)整':'鎖定'}}</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>
參數(shù)說明
參數(shù) | 類型 | 說明 |
---|---|---|
group | String/ Array group=“name” | 用于分組, 同一組的不同list可以相互拖動 |
list | Array | 設(shè)置拖拽元素 |
sort | Boolean :sort=“true” | 是否開啟內(nèi)部排序, 如果設(shè)為 false 則它所在的組無法排序 |
delay | Number :delay=“0” | 鼠標(biāo)選中后可以開始拖拽的延遲時間 |
touchStartThreshold | Number :touchStartThreshold=“5” | 鼠標(biāo)移動多少px才可以拖動元素 |
disabled | Boolean :disabled=“true” | 是否啟用拖拽組件 |
animation | Number :animation="1000"單位 ms | 拖動時過渡動畫效果 |
handle | Selector handle=“.card-title” | 拖動手柄,鼠標(biāo)移動到 css 名為 card-title 的選擇器時才能成為拖動手柄進(jìn)行拖動 |
filter | Selector filter=“.unmover” | 通過選擇器設(shè)置哪些樣式的元素不能被拖動 多個選擇器用 ‘,’ 分隔 |
preventOnFilter | Boolean :preventOnFilter="true"默認(rèn)觸發(fā) | 當(dāng)拖動filter時是否觸發(fā) event.preventDefault() |
draggable | Selector draggable=“.item” | 哪些元素時可以進(jìn)行拖動的 |
ghostClass | ghostClass=“ghost-style” | 設(shè)置拖拽元素的占位符樣式 模擬被拖動元素的排序情況,自定義樣式可能需要添加 !important 才能生效(forceFallback 屬性設(shè)置味 true) |
chosenClass | chosenClass=“chosen-style” | 設(shè)置目標(biāo)被選中時的樣式(包括拖拽時鼠標(biāo)附著的樣式)自定義樣式可能需要添加 !important 才能生效(forceFallback 屬性設(shè)置味 true) |
dragClass | dragClass=“drag-style” | 拖動元素過程中添加的樣式,自定義樣式可能需要添加 !important 才能生效(forceFallback 屬性設(shè)置味 true) |
dataIdAttr | Selector dataIdAttr=”data-id“ | 不太清楚 |
forceFallback | forceFallback=“true” 默認(rèn)為false | 設(shè)為 true 時將不使用原生的html5 的拖放,可修改拖放過程中的樣式 |
fallbackClass | fallback-class=“dragging_style” | forceFallback=“true” 時,克隆出新的DOM元素類名,可修改拖放過程中鼠標(biāo)附著的樣式 |
allbackOnBody | Boolean 默認(rèn)為false | allbackOnBody=“true” 時將克隆的元素添加到文檔的body中 |
fallbackTolerance | Number 單位 px | 拖拽之前應(yīng)該移動的距離 |
scroll | Boolean 默認(rèn)為true | 當(dāng)排序的容器是個可滾動的區(qū)域,拖放是否能引起區(qū)域滾動 |
scrollFn | Function | 滾動回調(diào)函數(shù),用于自定義滾動條的適配 |
scrollSensitivity | Number 默認(rèn)30 | 距離滾動區(qū)域多遠(yuǎn)時滾動條滾動,鼠標(biāo)靠近邊緣多遠(yuǎn)時開始滾動 |
scorllSpeed | Number | 滾動速度 |
事件
參數(shù) | 說明 | 回調(diào)參數(shù) |
---|---|---|
start | 開始拖動時 | function({ to, from, item, clone, oldIndex, newIndex }) |
add | 往列表中移入(添加)單元時 | function({ to, from, item, clone, oldIndex, newIndex }) |
remove | 單元被移動到另一個列表(從當(dāng)前的列表移處)時 | function({ to, from, item, clone, oldIndex, newIndex }) |
update | 排序發(fā)生變化時 | function({ to, from, item, clone, oldIndex, newIndex }) |
end | 拖拽結(jié)束時 | function({ to, from, item, clone, oldIndex, newIndex }) |
choose | 選擇單元格時 | function({ to, from, item, clone, oldIndex, newIndex }) |
sort | 排序發(fā)生變化時 | function({ to, from, item, clone, oldIndex, newIndex }) |
filter | 嘗試選擇一個被filter過濾的單元時 | function({ to, from, item, clone, oldIndex, newIndex }) |
clone | clone 復(fù)制出單元格時觸發(fā) | 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 占位符、拖動過程中鼠標(biāo)附著的副本樣式的共同樣式。
設(shè)置 :force-fallback=“true” 可修改拖放過程中的樣式
fallback-class 設(shè)置鼠標(biāo)附著的副本樣式, 通過 !important 提升樣式優(yōu)先級。
drag-class 拖拽過程中的樣式(鼠標(biāo)附著樣式 opacity: 1 !important; 設(shè)置副本的透明度)。
在拖拽過程中配置的類名作用的相應(yīng)區(qū)域:
總結(jié)
通過試用多個不同的組件庫,恍惚比較總結(jié),最后在項目重采用vuedraggable,因為該組件的實現(xiàn)方式簡單,并且能夠靈活控制拖拽的樣式,達(dá)到所需的效果。
到此這篇關(guān)于vue中實現(xiàn)拖拽排序功能的文章就介紹到這了,更多相關(guān)vue實現(xiàn)拖拽排序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
參考
smooth- dnd 參考自 : https://blog.51cto.com/u_15127632/4038149
vuedraggable 參考自:https://blog.csdn.net/Kiruthika/article/details/123903706
相關(guān)文章
Vue 數(shù)據(jù)響應(yīng)式相關(guān)總結(jié)
這篇文章主要介紹了Vue 數(shù)據(jù)響應(yīng)式的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)vue框架的使用,感興趣的朋友可以了解下2021-01-01vue組件屬性(props)及私有數(shù)據(jù)data解析
這篇文章主要介紹了vue組件屬性(props)及私有數(shù)據(jù)data解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10使用Vue開發(fā)自己的Chrome擴(kuò)展程序過程詳解
這篇文章主要介紹了使用Vue開發(fā)自己的Chrome擴(kuò)展程序過程詳解,瀏覽器擴(kuò)展程序是可以修改和增強(qiáng) Web 瀏覽器功能的小程序。它們可用于各種任務(wù),例如阻止廣告,管理密碼,組織標(biāo)簽,改變網(wǎng)頁的外觀和行為等等。,需要的朋友可以參考下2019-06-06