亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

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

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

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

屬性和事件

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

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

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

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

拖拽元素的事件事件

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

可放置目標(biāo)

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

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

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

做一個例子來理解 可放置目標(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 對象

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

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

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

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

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 編寫一個拖拽排序的列表大概分下面幾個步驟:

  • 創(chuàng)建一個列表,遍歷渲染到頁面
  • 列表項添加 draggable="true"
  • 列表項添加事件 dragstart dragenter dragend dragover
  • dragenter 事件中,需要傳入列表項的下標(biāo),實時進(jìn)行元素的排序。排序的核心邏輯也是在 dragenter
  • 代碼執(zhí)行的邏輯是:列表項拖拽到可放置目標(biāo)時,將該拖拽的元素從原位置刪除,再將拖拽的元素插入到當(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()
	// 拖拽到原位置時不觸發(fā)
	if (dragIndex !== index) {
		const source = drag.list[dragIndex];
		drag.list.splice(dragIndex, 1);
		drag.list.splice(index, 0, source);
		// 更新節(jié)點位置
		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>

此時是這樣的效果:

動畫.gif

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

添加代碼:

<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, /* 對移動中的元素應(yīng)用的過渡 */
    .list-enter-active,
    .list-leave-active {
        transition: all 0.2s ease;
    }
</style>

效果如下:

222.gif

sortable.js

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

Element Plus 是基于 Vue3 的常用的開源組件庫

安裝 sortable.js

npm i sortablejs -S

使用 el-table 組件,寫一個表格:

<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)在就有了一個表格:

捕獲.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 中,也就是組件掛載完成之后,實例化 Sortable(),傳入要進(jìn)行拖拽排序的節(jié)點 el 和其它一些配置參數(shù)?,F(xiàn)在可以進(jìn)行拖拽了。

333.gif

有些時候,可能需要按住拖動圖標(biāo)才可以進(jìn)行拖動,需要添加 handle 配置,并指定對應(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>

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

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

444.gif

查看其他配置項

vuedraggable

vue.draggable.next 是 Vue3 的拖拽組件,是基于 Sortable.js 實現(xiàn)的??梢杂糜谕献Я斜怼⒉藛?、工作臺、選項卡等常見的場景。

安裝:

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 為拖拽開始和結(jié)束時的事件。chosen-class 為拖拽時的樣式。

555.gif

為組件設(shè)置相同的 group 屬性,可以實現(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中列表拖拽排序的實現(xiàn)示例的文章就介紹到這了,更多相關(guān)Vue3 列表拖拽排序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue.js 實現(xiàn)評價五角星組件的實例代碼

    vue.js 實現(xiàn)評價五角星組件的實例代碼

    這篇文章主要介紹了vue.js 實現(xiàn)評價五角星組件的實例代碼,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-08-08
  • vue3自定義指令自動獲取節(jié)點的width和height代碼示例

    vue3自定義指令自動獲取節(jié)點的width和height代碼示例

    這篇文章主要介紹了如何使用ResizeObserver監(jiān)聽組件的寬度和高度,并將其封裝成一個指令以便全局或局部使用,ResizeObserver可以監(jiān)聽元素的多個尺寸屬性,如top、bottom、left等,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-11-11
  • vue微信分享出來的鏈接點開是首頁問題的解決方法

    vue微信分享出來的鏈接點開是首頁問題的解決方法

    這篇文章主要為大家詳細(xì)介紹了vue微信分享出來的鏈接點開是首頁問題的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • vuex中五大屬性和使用說明(包括輔助函數(shù))

    vuex中五大屬性和使用說明(包括輔助函數(shù))

    這篇文章主要介紹了vuex中五大屬性和使用說明(包括輔助函數(shù)),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • vue項目如何配置public靜態(tài)資源路徑訪問

    vue項目如何配置public靜態(tài)資源路徑訪問

    這篇文章主要介紹了vue項目如何配置public靜態(tài)資源路徑訪問方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • vue實現(xiàn)仿淘寶結(jié)賬頁面實例代碼

    vue實現(xiàn)仿淘寶結(jié)賬頁面實例代碼

    本文是小編給大家分享的vue實現(xiàn)仿淘寶結(jié)賬頁面實例代碼,主要功能是仿照淘寶頁面的結(jié)算購物車商品時自動算出合計價格的頁面,具體實例代碼大家參考下本文
    2017-11-11
  • 詳解element-ui日期時間選擇器的日期格式化問題

    詳解element-ui日期時間選擇器的日期格式化問題

    這篇文章主要介紹了詳解element-ui日期時間選擇器的日期格式化問題,本文用到了DateTimePicker來選擇日期時間,但是在將數(shù)據(jù)傳回后臺的過程中遇到了一些令人頭疼的問題,有興趣的一起來了解一下
    2019-04-04
  • vue過渡和animate.css結(jié)合使用詳解

    vue過渡和animate.css結(jié)合使用詳解

    本篇文章主要介紹了vue過渡和animate.css結(jié)合使用詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • Vue?router?路由守衛(wèi)詳解

    Vue?router?路由守衛(wèi)詳解

    這篇文章主要為大家介紹了Vue?router?路由守衛(wèi),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • 詳解Vue路由自動注入實踐

    詳解Vue路由自動注入實踐

    這篇文章主要介紹了詳解Vue路由自動注入實踐,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04

最新評論