日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Vue 可拖拽組件Vue Smooth DnD的使用詳解

瀏覽:171日期:2023-02-08 10:03:13
目錄簡介和 Demo 展示API: Container屬性生命周期回調事件API: Draggable實戰簡介和 Demo 展示

最近需要有個拖拽列表的需求,發現一個簡單好用的 Vue 可拖拽組件。安利一下~

Vue Smooth DnD 是一個快速、輕量級的拖放、可排序的 Vue.js 庫,封裝了 smooth-dnd 庫。

Vue Smooth DnD 主要包含了兩個組件,Container 和 Draggable,Container 包含可拖動的元素或組件,它的每一個子元素都應該被 Draggable 包裹。每一個要被設置為可拖動的元素都需要被 Draggable 包裹。

安裝: npm i vue-smooth-dnd

一個簡單的 Demo ,展示組件的基礎用法,實現了可以拖拽的列表。

<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 } = dragResultconsole.log(removedIndex, addedIndex, payload)if (removedIndex === null && addedIndex === null) return arrconst result = [...arr]let itemToAdd = payloadif (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, .125);margin-bottom: 2px;margin-top: 2px;cursor: default;user-select: none; }</style>

效果

Vue 可拖拽組件Vue Smooth DnD的使用詳解

API: Container屬性

屬性 類型 默認值 描述 :orientation string vertical 容器的方向,可以為 horizontal 或 vertical :behaviour string move 描述被拖動的元素被移動或復制到目標容器。 可以為 move 或 copy 或 drop-zone 或 contain 。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 選擇器,如果不指定的話則元素內部任意位置都可抓取。 :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

關于 drag-class,drop-class 和 drop-placeholder.className 的效果演示

<Container # 省略其它屬性...:animation-duration='1000' # 放置元素后動畫延時drag- drop- :drop-placeholder='{ className: ’drop-preview’, # 占位符的樣式 animationDuration: ’1000’, # 占位符的動畫延遲 showOnTop: true # 是否在其它元素的上面顯示 設置為false會被其他的拖拽元素覆蓋}'> <!-- 一些可拖拽元素 --> <Draggable>....</Draggable></Container>

類對應樣式

.card-ghost { transition: transform 0.18s ease; transform: rotateZ(35deg); background: red !important;}.card-ghost-drop { transition: transform 1s cubic-bezier(0,1.43,.62,1.56); transform: rotateZ(0deg); background: green !important;}.drop-preview { border: 1px dashed #abc; margin: 5px; background: yellow !important;}

實際效果(我這優秀的配色啊)

Vue 可拖拽組件Vue Smooth DnD的使用詳解

生命周期

一次拖動的生命周期通過一系列回調和事件進行描述和控制,下面以包含 3 個容器的示例為例進行說明(直接復制了文檔沒有翻譯,API 詳細解釋可以看后面介紹。):

Mouse Calls Callback / Event Parameters Notesdown o Initial clickmove o Initial drag | | get-child-payload() index Function should return payload | | 3 x should-accept-drop() srcOptions, payload Fired for all containers | | 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 3 x drag-end dragResult Fired for all containers n x drop dropResult Fired only for droppable containers

請注意,應在每次 drag-start 之前和每次 drag-end 之前觸發 should-accept-drop,但為了清晰起見,此處已省略。

其中 dragResult 參數的格式:

dragResult: { payload,# 負載 可以理解為用來記錄被拖動的對象 isSource, # 是否是被拖動的容器本身 willAcceptDrop, # 是否可以被放置}

其中 dropResult 參數的格式:

dropResult: { addedIndex, # 被放置的新添加元素的下標,沒有則為 null removedIndex, # 將被移除的元素下標,沒有則為 null payload,# 拖動的元素對象,可通過 getChildPayload 指定 droppedElement, # 放置的 DOM 元素}回調

回調在用戶交互之前和期間提供了額外的邏輯和檢查。

get-child-payload(index) 自定義傳給 onDrop() 的 payload 對象。 should-accept-drop(sourceContainerOptions, payload) 用來確定容器是否可被放置,會覆蓋 group-name 屬性。 should-animate-drop(sourceContainerOptions, payload) 返回 false 則阻止放置動畫。 get-ghost-parent() 返回幽靈元素(拖動時顯示的元素)應該添加到的元素,默認是父元素,某些情況定位會出現問題,則可以選擇自定義,如返回 document.body。事件 @drag-start 在拖動開始時由所有容器發出的事件。參數 dragResult。 @drag-end 所有容器在拖動結束時調用的函數。 在 @drop 事件之前調用。參數 dragResult。 @drag-enter 每當拖動的項目在拖動時進入其邊界時,相關容器要發出的事件。 @drag-leave 每當拖動的項目在拖動時離開其邊界時,相關容器要發出的事件。 @drop-ready 當容器中可能放置位置的索引發生變化時,被拖動的容器將調用的函數。基本上,每次容器中的可拖動對象滑動以打開拖動項目的空間時都會調用它。參數 dropResult。 @drop 放置結束時所有相關容器會發出的事件(放置動畫結束后)。源容器和任何可以接受放置的容器都被認為是相關的。參數 dropResult。API: Draggable

tag

同容器的 tag 指定可拖拽元素的 DOM 元素標簽。

實戰

實現一個簡單的團隊協作任務管理器。

<template> <div class='card-scene'><Containerorientation='horizontal'@drop='onColumnDrop($event)'drag-handle-selector='.column-drag-handle'> <Draggable v-for='column in taskColumnList' :key='column.name'><div class='card-container'> <div class='card-column-header'><span class='column-drag-handle'>&#x2630;</span>{{ column.name }} </div> <Container group-name='col' @drop='(e) => onCardDrop(column.id, e)' :get-child-payload='getCardPayload(column.id)' drag- drop- :drop-placeholder='dropPlaceholderOptions' ><Draggable v-for='task in column.list' :key='task.id'> <div class='task-card'><div class='task-title'>{{ task.name }}</div><div :style='{ background: priorityMap[task.priority].color }'> {{ priorityMap[task.priority].label }}</div> </div></Draggable> </Container></div> </Draggable></Container> </div></template><script> import { Container, Draggable } from 'vue-smooth-dnd'; const applyDrag = (arr, dragResult) => {const { removedIndex, addedIndex, payload } = dragResultconsole.log(removedIndex, addedIndex, payload)if (removedIndex === null && addedIndex === null) return arrconst result = [...arr]let itemToAdd = payloadif (removedIndex !== null) { itemToAdd = result.splice(removedIndex, 1)[0]}if (addedIndex !== null) { result.splice(addedIndex, 0, itemToAdd)}return result } const taskList = [{ name: ’首頁’, priority: ’P1’, status: ’待開發’, id: 1,},{ name: ’流程圖開發’, priority: ’P3’, status: ’待評審’, id: 2,},{ name: ’統計圖展示’, priority: ’P0’, status: ’開發中’, id: 3,},{ name: ’文件管理’, priority: ’P1’, status: ’開發中’, id: 4,} ] const statusList = [’待評審’, ’待開發’, ’開發中’, ’已完成’] const taskColumnList = statusList.map((status, index) => {return { name: status, list: taskList.filter(item => item.status === status), id: index} }) const priorityMap = {’P0’: { label: ’最高優’, color: ’#ff5454’,},’P1’: { label: ’高優’, color: ’#ff9a00’,},’P2’: { label: ’中等’, color: ’#ffd139’,},’P3’: { label: ’較低’, color: ’#1ac7b5’,}, } export default {name: ’Cards’,components: {Container, Draggable},data () { return {taskColumnList,priorityMap,dropPlaceholderOptions: { className: ’drop-preview’, animationDuration: ’150’, showOnTop: true} }},methods: { onColumnDrop (dropResult) {this.taskColumnList = applyDrag(this.taskColumnList, dropResult) }, onCardDrop (columnId, dropResult) {let { removedIndex, addedIndex, payload } = dropResultif (removedIndex !== null || addedIndex !== null) { const column = taskColumnList.find(p => p.id === columnId) if (addedIndex !== null && payload) { // 更新任務狀態dropResult.payload = { ...payload, status: column.name,} } column.list = applyDrag(column.list, dropResult)} }, getCardPayload (columnId) {return index => this.taskColumnList.find(p => p.id === columnId).list[index] },} }</script><style> * {margin: 0;padding: 0;font-family: ’Microsoft YaHei’,’PingFang SC’,’Helvetica Neue’,Helvetica,sans-serif;line-height: 1.45;color: rgba(0,0,0,.65); } .card-scene {user-select: none;display: flex;height: 100%;margin: 20px; } .card-container {display: flex;flex-direction: column;width: 260px;min-width: 260px;border-radius: 12px;background-color: #edeff2;margin-right: 16px;height: calc(100vh - 40px); } .card-column-header {display: flex;height: 50px;margin: 0 16px;align-items: center;flex-shrink: 0;font-weight: 500;font-size: 16px; } .draggable-container {flex-grow: 1;overflow: auto; } .column-drag-handle {cursor: move;padding: 5px; } .task-card {margin: 10px;background-color: white;padding: 15px 10px;border-radius: 8px;box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.12);cursor: pointer;display: flex;justify-content: space-between; } .task-title {color: #333333;font-size: 14px; } .task-priority {width: 60px;line-height: 20px;border-radius: 12px;text-align: center;color: #fff;font-size: 12px; } .card-ghost {transition: transform 0.18s ease;transform: rotateZ(5deg) } .card-ghost-drop {transition: transform 0.18s ease-in-out;transform: rotateZ(0deg) } .drop-preview {background-color: rgba(150, 150, 200, 0.1);border: 1px dashed #abc;margin: 5px; }</style>

效果

Vue 可拖拽組件Vue Smooth DnD的使用詳解

到此這篇關于Vue 可拖拽組件Vue Smooth DnD的使用詳解的文章就介紹到這了,更多相關Vue 可拖拽組件內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Vue
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
一级欧洲+日本+国产| 91欧美精品| 国产精品二区不卡| 福利一区视频| 欧美影院三区| 亚洲免费激情| 亚洲精品激情| 欧美激情亚洲| 久久久人人人| 亚洲欧美日本国产| 欧美激情麻豆| 精品日韩毛片| 国产亚洲高清一区| 成人一区而且| 欧美精品激情| 日韩欧乱色一区二区三区在线| 91成人超碰| 伊人久久大香线蕉av超碰演员| 69精品国产久热在线观看| 欧美日本久久| 国产精品啊v在线| 97精品在线| 久久福利影视| 久久97视频| 日韩亚洲在线| 国产欧美另类| 91成人精品视频| 美女久久久久久 | 日韩高清不卡在线| 国产精品久久久久久妇女 | 欧美日韩在线播放视频| 91精品啪在线观看国产18| 黄色在线一区| 国产亚洲第一伦理第一区| 日韩毛片在线| 国产伦理一区| 亚洲精品极品少妇16p| 国产毛片精品| 亚洲综合丁香| 亚洲美女久久精品| 欧美日韩伊人| 在线午夜精品| 亚洲国产福利| 国产亚洲人成a在线v网站| 好吊日精品视频| 精品一区不卡| 蜜桃av一区| 91亚洲自偷观看高清| 午夜视频一区二区在线观看| 日韩精品欧美| 欧美a在线观看| 日本不卡不码高清免费观看| 免费毛片在线不卡| 精品美女视频| 日韩av网站在线免费观看| 欧美福利一区| 国产成人精品福利| 中文字幕日韩欧美精品高清在线| 国产精品人人爽人人做我的可爱| 国产一区二区三区亚洲| 欧美午夜网站| 欧美在线观看视频一区| 成人日韩av| 日本va欧美va欧美va精品| 亚洲免费高清| 亚洲手机视频| 久久精品亚洲人成影院 | 国产精品亚洲片在线播放| 国产韩日影视精品| 日韩高清不卡| 色综合狠狠操| 嫩草伊人久久精品少妇av杨幂| 久久亚洲国产精品尤物| 男女男精品视频网| 亚洲www啪成人一区二区| 久久亚洲精精品中文字幕| 国产欧美日韩在线一区二区| 免费视频最近日韩| 六月天综合网| 日韩天堂av| 黄色免费成人| 久久成人精品| 一区二区国产在线观看| 久久高清国产| 蜜臀av一区二区三区| 美女国产精品| 亚洲香蕉久久| 免费成人性网站| 伊人成人在线视频| 国产精品日韩久久久| 欧美日韩国产综合网| 亚洲欧洲午夜| 蜜桃传媒麻豆第一区在线观看| 久久国产人妖系列| 亚洲精品在线国产| 91国内精品| 国产精品久久777777毛茸茸| 欧美精品1区| 国际精品欧美精品| 超碰超碰人人人人精品| 99久精品视频在线观看视频| 激情婷婷欧美| 视频一区欧美日韩| 日韩精品1区2区3区| 国产精品一区免费在线| 福利片在线一区二区| 97精品一区| 黄色成人91| 青青国产91久久久久久| 国产日韩免费| 红杏一区二区三区| 99久久婷婷| 日韩一区精品视频| 国产欧美丝祙| 国产v综合v| 日韩一区欧美二区| 美女免费视频一区| 99久久精品费精品国产| 国产美女精品| 欧美日韩精品一区二区三区在线观看| 99精品国产一区二区三区| 亚洲特色特黄| 亚洲精品在线国产| 欧美激情91| 欧美日韩一区二区综合| 四虎精品永久免费| а√天堂8资源中文在线| 99亚洲视频| 里番精品3d一二三区| 超碰成人av| 香蕉精品999视频一区二区| 日本欧美在线| 日韩国产一区| 水野朝阳av一区二区三区| 久久激情综合网| 日韩成人亚洲| 日韩av资源网| 美女网站视频一区| 日本v片在线高清不卡在线观看| 午夜久久福利| 青草av.久久免费一区| 日韩欧美精品一区| 亚洲精品九九| 99成人在线视频| 国产精品日韩精品在线播放| 久久九九精品| 国产精品流白浆在线观看| 亚洲国内精品| 国产精品115| 久久久久国产| 久久99久久人婷婷精品综合| 欧美日韩黑人| 美女国产精品久久久| 亚洲欧美不卡| 精品高清久久| 日本视频在线一区| 免费视频国产一区| 精品久久久久中文字幕小说| 久久高清国产| 久久婷婷久久| 九九九精品视频| 亚洲久久在线| 欧美成人午夜| 国产一区二区色噜噜| 亚洲综合激情在线| 久久精品国语| 日韩a一区二区| 国产精品亚洲欧美| 日韩精品一二三四| 欧美日韩在线网站| 荡女精品导航| 国产香蕉精品| 偷拍亚洲精品| 国产视频一区在线观看一区免费| 激情综合网站| 国产成人1区| 日本精品另类| 日韩中文字幕91| 日韩精品中文字幕第1页| 国产日韩欧美一区二区三区| 亚洲精品日本| 一区二区亚洲视频| 先锋亚洲精品| 9色精品在线| 欧美亚洲国产一区| 视频在线不卡免费观看| 精品一区91| 久久精品三级| 国产剧情在线观看一区| 天海翼亚洲一区二区三区| 欧美精品一卡| 国产视频亚洲| 国产亚洲精品久久久久婷婷瑜伽| 亚洲欧洲一区二区天堂久久| 久久久久久自在自线| 久久只有精品| 久久久国产精品网站| 久久久免费人体| 国产日产一区| 日韩国产在线观看一区|