欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue3中列表拖拽排序的實(shí)現(xiàn)示例

 更新時(shí)間:2023年06月14日 09:37:56   作者:KONG  
本文主要介紹了Vue3中列表拖拽排序的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

本文主要內(nèi)容分三個(gè)部分。先寫(xiě)了在 Vue3 中利用 HTML5draggable 屬性手寫(xiě)實(shí)現(xiàn)列表拖拽排序的功能。接下來(lái)記錄了在 Element Plus 組件庫(kù)中結(jié)合 sortable.js 使用,對(duì)表格組件 el-table進(jìn)行拖拽排序的。最后一個(gè)部分是 vuedraggable 拖拽組件的使用。

本文基于 ViteVue3、Element Plus 技術(shù)棧

draggable 實(shí)現(xiàn)拖拽排序

屬性和事件

draggable 屬性是 HTML5 新增的可拖拽屬性。

在 HTML 中,除了圖像、鏈接和選擇的文本默認(rèn)可拖拽外,其他元素默認(rèn)是不可拖拽的。如果想讓其他元素變成可拖拽的,首先需要把 draggable 屬性設(shè)置為 true

<p draggable="true"> 可拖拽</p>

設(shè)置完成之后,還需要結(jié)合一些事件才能完成拖拽:

拖拽元素的事件事件

  • 拖拽元素的事件
事件觸發(fā)時(shí)機(jī)
dragstart開(kāi)始拖拽時(shí)執(zhí)行 1 次
drag拖拽開(kāi)始后多次觸發(fā)
dragend拖動(dòng)結(jié)束后觸發(fā) 1 次
  • 可釋放目標(biāo)的事件
事件觸發(fā)時(shí)機(jī)
dragenter拖拽元素進(jìn)入可釋放目標(biāo)時(shí)執(zhí)行 1 次
dragover拖拽元素進(jìn)入可釋放目標(biāo)時(shí)觸發(fā)多次(100毫秒觸發(fā)一次)
drop拖拽元素進(jìn)入可釋放目標(biāo)內(nèi)釋放時(shí)(設(shè)置了dragover此事件才會(huì)生效)

可放置目標(biāo)

dragenter 或 dragover事件可用于表示有效的放置目標(biāo),也就是被拖拽元素可能放置的地方。

設(shè)置允許被被放置還需要阻止 dragenter 和 dragover 事件的默認(rèn)處理。

<div ondragenter="event.preventDefault()">

做一個(gè)例子來(lái)理解 可放置目標(biāo)

<div id="div"
  ondragover="dragover(event)"
  ondragenter="dragenter(event)""
 >
    我是可放置目標(biāo)
</div>
<p id="drag" 
  draggable="true" 
  ondragstart="dragstart(event)"
  ondragend="dragend(event)" 
>
    我是拖拽元素,把我拖拽到上面去
</p>
#div {
  width:300px;
  height:80px;
  padding:10px;
  border:1px solid gray;
}
let targetDom
function dragstart(e) {
}
function dragenter(e) {
  e.preventDefault()
  targetDom = e.target
}
function dragover(e) {
  e.preventDefault()
  e.dataTransfer.dropEffect = 'move'
}
function dragend(e) {
  e.preventDefault()
  targetDom.appendChild(e.target)
}

DataTransfer 對(duì)象

DataTransfer 對(duì)象用于保存拖拽過(guò)程中的數(shù)據(jù)、設(shè)置拖動(dòng)類(lèi)型等。在所有拖動(dòng)事件 event的 dataTransfer 屬性上都能獲取到 DataTransfer 對(duì)象。

dataTransfer.dropEffect設(shè)置拖拽的操作類(lèi)型。值必須是nonecopylink 或 move

function dragover(e) {
    e.preventDefault()
    e.dataTransfer.dropEffect = 'move'
}

傳遞數(shù)據(jù) (不建議使用這種方法,可能有兼容問(wèn)題)只能在drop事件中接收(測(cè)試的時(shí)候在其他拖拽事件中獲取不到)

function dragstart(e, index) {
	e.stopPropagation()
	e.dataTransfer.dropEffect = 'move'
        // 傳數(shù)據(jù)
	e.dataTransfer.setData('text/plain', '111111111')
}
function drop(e) {
        // 接收數(shù)據(jù)
	console.log(e.dataTransfer.getData('text/plain'));
}

Vue3 中拖拽排序

根據(jù)上面描述的屬性和事件在 Vue3 編寫(xiě)一個(gè)拖拽排序的列表大概分下面幾個(gè)步驟:

  • 創(chuàng)建一個(gè)列表,遍歷渲染到頁(yè)面
  • 列表項(xiàng)添加 draggable="true"
  • 列表項(xiàng)添加事件 dragstart dragenter dragend dragover
  • dragenter 事件中,需要傳入列表項(xiàng)的下標(biāo),實(shí)時(shí)進(jìn)行元素的排序。排序的核心邏輯也是在 dragenter
  • 代碼執(zhí)行的邏輯是:列表項(xiàng)拖拽到可放置目標(biāo)時(shí),將該拖拽的元素從原位置刪除,再將拖拽的元素插入到當(dāng)前可放置目標(biāo)的位置

代碼如下:

<template>
    <div>
            <div
                class="item"
                v-for="(item, i) in drag.list"
                :key="item.id"
                draggable="true"
                @dragstart="dragstart($event, i)"
                @dragenter="dragenter($event, i)"
                @dragend="dragend"
                @dragover="dragover"
               >
                {{ item.name }}
            </div>
    </div>
</template>
<script setup>
import { reactive } from 'vue'
const drag = reactive({
	list: [
		{ name: 'a', id: 1 },
		{ name: 'b', id: 2 },
		{ name: 'c', id: 3 },
		{ name: 'd', id: 4 },
		{ name: 'e', id: 5 },
	]
})
let dragIndex = 0
function dragstart(e, index) {
	e.stopPropagation()
	dragIndex = index
	setTimeout(() => {
		e.target.classList.add('moveing')
	},0)
}
function dragenter(e, index) {
	e.preventDefault()
	// 拖拽到原位置時(shí)不觸發(fā)
	if (dragIndex !== index) {
		const source = drag.list[dragIndex];
		drag.list.splice(dragIndex, 1);
		drag.list.splice(index, 0, source);
		// 更新節(jié)點(diǎn)位置
		dragIndex = index
	}
}
function dragover(e) {
	e.preventDefault()
	e.dataTransfer.dropEffect = 'move'
}
function dragend(e) {
	e.target.classList.remove('moveing')
}
</script>
<style lang="scss" scoped>
.item {
	width: 200px;
	height: 40px;
	line-height: 40px;
	// background-color: #f5f6f8;
	background-color: skyblue;
	text-align: center;
	margin: 10px;
	color: #fff;
	font-size: 18px;
}
.container {
  position: relative;
  padding: 0;
}
.moveing {
	opacity: 0;
}
</style>

此時(shí)是這樣的效果:

動(dòng)畫(huà).gif

這樣就在 Vue3 中實(shí)現(xiàn)了拖拽排序。還可以利用 Vue 的<TransitionGroup> 內(nèi)置組件,添加動(dòng)畫(huà)效果,讓元素的過(guò)渡不會(huì)很生硬。

添加代碼:

<template>
<div>
	<TransitionGroup name="list" tag="div" class="container">
		<div
			class="item"
			v-for="(item, i) in drag.list"
			:key="item.id"
			draggable="true"
			@dragstart="dragstart($event, i)"
			@dragenter="dragenter($event, i)"
			@dragend="dragend"
			@dragover="dragover"
		>
			{{ item.name }}
		</div>
	</TransitionGroup>
</div>
</template>
<style lang="scss" scoped>
    .list-move, /* 對(duì)移動(dòng)中的元素應(yīng)用的過(guò)渡 */
    .list-enter-active,
    .list-leave-active {
        transition: all 0.2s ease;
    }
</style>

效果如下:

222.gif

sortable.js

接下來(lái)在 Element Plus 組件庫(kù)中使用 sortable.js 進(jìn)行表格排序。

Element Plus 是基于 Vue3 的常用的開(kāi)源組件庫(kù)

安裝 sortable.js

npm i sortablejs -S

使用 el-table 組件,寫(xiě)一個(gè)表格:

<template>
<div>
        <el-table :data="tableData" id="dragTable" border style="width: 800px;">
                <el-table-column prop="date" label="Date" width="180" />
                <el-table-column prop="name" label="Name" width="180" />
                <el-table-column prop="address" label="Address" />
        </el-table>
</div>
</template>
<script setup>
const tableData = [
	{
		date: '2016-05-03',
		name: 'Tom',
		address: 'No. 189, Grove St, Los Angeles',
	},
	{
		date: '2016-05-02',
		name: 'Cilly',
		address: 'No. 189, Grove St, Los Angeles',
	},
	{
		date: '2016-05-04',
		name: 'Linda',
		address: 'No. 189, Grove St, Los Angeles',
	},
	{
		date: '2016-05-01',
		name: 'John',
		address: 'No. 189, Grove St, Los Angeles',
	},
]
</script>

現(xiàn)在就有了一個(gè)表格:

捕獲.PNG

然后導(dǎo)入 sortable.js

<script setup>
import Sortable from 'sortablejs'
import { onMounted } from 'vue'
function setSort() {
    const el = document.querySelector('#dragTable table tbody')
    new Sortable(el, {
    sort: true,
		ghostClass: 'sortable-ghost',
		onEnd: (e) => {
			const targetRow = tableData.splice(e.oldIndex, 1)[0]
			tableData.splice(e.newIndex, 0, targetRow)
			console.log(tableData)
		},
	})
}
onMounted(() => {
	setSort()
})
const tableData = [
 // ...
]
</script>

onMounted 中,也就是組件掛載完成之后,實(shí)例化 Sortable(),傳入要進(jìn)行拖拽排序的節(jié)點(diǎn) el 和其它一些配置參數(shù)?,F(xiàn)在可以進(jìn)行拖拽了。

333.gif

有些時(shí)候,可能需要按住拖動(dòng)圖標(biāo)才可以進(jìn)行拖動(dòng),需要添加 handle 配置,并指定對(duì)應(yīng)的樣式名。

    <el-table :data="tableData" id="dragTable" border style="width: 600px; margin: 20px">
      <!-- ...... 省略代碼 -->
      <el-table-column label="操作" width="100">
        <template #default>
          <div class="handle-drag">
            <el-icon>
              <Sort />
            </el-icon>
          </div>
        </template>
      </el-table-column>
    </el-table>

上面代碼將表格添加了一個(gè)操作列,并將操作列的圖標(biāo)設(shè)置一個(gè)樣式類(lèi)。下面的配置表示只有包含.handle-drag 樣式的元素才可以被拖動(dòng)。其他位置不能被拖動(dòng)。

  new Sortable(el, {
    // ...
    handle: '.handle-drag',
    // ...
  })

444.gif

查看其他配置項(xiàng)

vuedraggable

vue.draggable.next 是 Vue3 的拖拽組件,是基于 Sortable.js 實(shí)現(xiàn)的??梢杂糜谕献Я斜?、菜單、工作臺(tái)、選項(xiàng)卡等常見(jiàn)的場(chǎng)景。

安裝:

npm i -S vuedraggable@next

使用:

<script setup>
import draggable from 'vuedraggable'
import { reactive } from 'vue'
const state = reactive({
	list1: [1, 2, 3, 4],
	list2: ['a', 'b', 'c', 'd'],
})
function onStart() {}
function onEnd() {
	console.log(state)
}
</script>

先導(dǎo)入 draggable并定義一些基礎(chǔ)數(shù)據(jù)。

<template>
	<div style="margin-left: 30px;">
		<draggable
			:list="state.list1"
			:force-fallback="true"
			chosen-class="chosen"
			animation="300"
			@start="onStart"
			@end="onEnd"
		>
			<template #item="{ element }">
				<div class="item">
					{{ element }}
				</div>
			</template>
		</draggable>
	</div>
</template>

其中 @start@end 為拖拽開(kāi)始和結(jié)束時(shí)的事件。chosen-class 為拖拽時(shí)的樣式。

555.gif

為組件設(shè)置相同的 group 屬性,可以實(shí)現(xiàn)在不同的塊之間拖拽。

<draggable group="group" :list="state.list1" >
			<template #item="{ element }">
				<div class="item bck1">
					{{ element }}
				</div>
			</template>
		</draggable>
		<draggable group="group" :list="state.list2" >
			<template #item="{ element }">
				<div class="item bck2">
					{{ element }}
				</div>
			</template>
		</draggable>

666.gif

相關(guān)地址

sortable.js 

vue.draggable.next

到此這篇關(guān)于Vue3中列表拖拽排序的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Vue3 列表拖拽排序內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論