Vue 끌 어 당 길 수 있 는 구성 요소 Vue Smooth DnD 사용 설명
                                            
 19170 단어  Vue드래그 가능 구성 요소
                    
최근 에 끌 어 당 기 는 목록 이 필요 합 니 다.간단 하고 사용 하기 좋 은 Vue 가 끌 어 당 길 수 있 는 구성 요 소 를 발 견 했 습 니 다.앤 리 해~
Vue Smooth DnD 은 빠 르 고 가 벼 운 드래그 앤 드 롭,정렬 이 가능 한 Vue.js 라 이브 러 리 로 smooth-dnd 라 이브 러 리 를 봉 했다.
Vue Smooth DnD 는 주로 두 개의 구성 요 소 를 포함 하고
Container 과 Draggable,Container 은 드래그 가능 한 요소 나 구성 요 소 를 포함 하 며 모든 하위 요 소 는 Draggable 으로 감 싸 야 합 니 다.드래그 가능 한 요소 로 설정 하려 면 Draggable 패키지 가 필요 합 니 다.설치:
npm i vue-smooth-dnd구성 요소 의 기본 사용법 을 보 여 주 는 간단 한 데모 로 끌 수 있 는 목록 을 만 들 었 습 니 다.
<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, .125);
        margin-bottom: 2px;
        margin-top: 2px;
        cursor: default;
        user-select: none;
    }
</style>효과.
 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-class="card-ghost"         
        drop-class="card-ghost-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;
}실제 효과(이 훌륭 한 배색 아)
 라 이 프 사이클
한 번 드래그 하 는 생명 주 기 는 일련의 반전 과 사건 을 통 해 설명 하고 제어 하 며,다음은 3 개의 용 기 를 포함 하 는 예 를 들 어 설명 한다.
(문서 가 번역 되 지 않 은 것 을 직접 복 사 했 습 니 다.API 의 상세 한 설명 은 뒤에 설명 할 수 있 습 니 다.)
Mouse     Calls  Callback / Event       Parameters              Notes
down   o                                                        Initial click
move   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
       v
move   o                                                        Drag over containers
       |
       |   n x   drag-leave                                     Fired as draggable leaves container
       |   n x   drag-enter                                     Fired as draggable enters container
       v
up     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.tag같은 용기 의 tag 에서 원 소 를 끌 어 당 길 수 있 는 DOM 요소 라벨 을 지정 합 니 다.실전
간단 한 팀워크 임무 관리 자 를 실현 하 다.
<template>
    <div class="card-scene">
        <Container
                orientation="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">☰</span>
                        {{ column.name }}
                    </div>
                    <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>
                </div>
            </Draggable>
        </Container>
    </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 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 } = dropResult
                if (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 끌 어 당 길 수 있 는 구성 요소 내용 은 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 부탁드립니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Vue Render 함수로 DOM 노드 코드 인스턴스 만들기render에서createElement 함수를 사용하여 DOM 노드를 만드는 것은 직관적이지 않지만 일부 독립 구성 요소의 디자인에서 특수한 수요를 충족시킬 수 있습니다.간단한 렌더링 예는 다음과 같습니다. 또한 v...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.