이번에는 Element-UI 테이블을 사용하여 드래그 앤 드롭 기능을 구현하는 방법에 대해 소개하겠습니다. Element-UI 테이블을 사용하여 드래그 앤 드롭 기능을 구현하는 경우 다음은 실제 사례입니다. 봐.
Element-UI의 테이블 구성 요소는 매우 강력하지만 우리의 요구 사항은 훨씬 더 강력합니다...
간단하고 투박한 렌더링:
1. 데이터 기반
전통적인 드래그 효과는 모두 mousedown, mousemove, mouseup 이벤트
를 통해 dom 노드 수정 및 삭제를 기반으로 하지만 Vue는 데이터 기반 프런트엔드 프레임워크이므로 개발 중에 dom 운영을 피해야 합니다
그리고 Element의 Table 구성 요소 -UI는 캡슐화되어 있습니다. 매우 엄격하여 DOM을 직접 조작하면 예측할 수 없는 버그가 쉽게 발생할 수 있습니다.
그래서 내 핵심 아이디어는 다음과 같습니다. 테이블 헤더(열)를 배열을 통해 렌더링한 다음 배열 순서를 수정하여 열을 수정합니다. sorting of the list
템플릿 부분:
<p class="w-table" :class="{'w-table_moving': dragState.dragging}"> <el-table :data="data" :border="option.border" :height="option.height" :max-height="option.maxHeight" :style="{ width: parseInt(option.width)+'px' }" :header-cell-class-name="headerCellClassName" > <slot name="fixed"></slot> <el-table-column v-for="(col, index) in tableHeader" :key="index" :prop="col.prop" :label="col.label" :width="col.width" :min-width="col.minWidth" :type="col.type" :header-align="col.headerAlign" :column-key="index.toString()" :render-header="renderHeader" > </el-table-column> </el-table> </p>
위 데이터는 목록 데이터 모음, 옵션은 Table 컴포넌트 구성 항목, header는 상위 컴포넌트에서 전달되는 테이블 헤더 데이터 모음
props: { data: { default: function () { return [] }, type: Array }, header: { default: function () { return [] }, type: Array }, option: { default: function () { return {} }, type: Object } }
구성 항목은 Element-UI
의 API에 따라 삭제될 수 있습니다.그러나 구성 요소 내부에서 사용되는 여러 매개 변수가 있습니다:
1.header-cell-class-name
은 다음과 같은 함수에 바인딩됩니다. 드래그하는 동안 점선 효과를 얻으려면 헤더 셀에 클래스를 동적으로 추가하세요.
2.column-key
는 헤더 배열의 인덱스에 바인딩되어 수정이 필요한 헤더 요소의 첨자를 결정하는 데 사용됩니다
3.render-header
테이블 헤더 렌더링 기능 , 사용자 정의를 추가하는 데 사용됨 mousemove 및 기타 관련 이벤트를 모니터링하는 방법
2. 드래그 상태 기록
드래그 프로세스 중에 몇 가지 주요 매개 변수를 기록해야 합니다.
data () { return { tableHeader: this.header, dragState: { start: -1, // 起始元素的 index end: -1, // 结束元素的 index move: -1, // 移动鼠标时所覆盖的元素 index dragging: false, // 是否正在拖动 direction: undefined // 拖动方向 } } }
또한 상위 요소는 헤더를 전달합니다. 데이터 헤더인데 드래그가 완료되었습니다. 이 데이터는 나중에 수정됩니다
자식 컴포넌트에서 상위 요소의 데이터를 직접 수정하는 것은 권장하지 않으므로 여기에서 tableHeader를 초기화하여 헤더 데이터 헤더를 호스팅합니다
하지만 헤더 수정을 허용하려면 tableHeader도 수정에 응답할 수 있습니다. 모니터 watch
watch: { header (val, oldVal) { this.tableHeader = val } }
를 추가해야 합니다. 3. 헤더
Element-UI의 Table 구성 요소를 사용자 정의하여 [drag the] 기능을 구현합니다. 열 너비 수정을 위한 테두리], mousemove, mouseup, mousedown이 없습니다. 이벤트가 노출됩니다
따라서 헤더를 사용자 정의하고 마우스 이벤트에 대한 핸들러 함수를 수동으로 추가해야 합니다. 이를 위해서는 renderHeader() 를 사용해야 합니다. method
renderHeader (createElement, {column}) { return createElement( 'p', { 'class': ['thead-cell'], on: { mousedown: ($event) => { this.handleMouseDown($event, column) }, mouseup: ($event) => { this.handleMouseUp($event, column) }, mousemove: ($event) => { this.handleMouseMove($event, column) } } }, [ // 添加 <a> 用于显示表头 label createElement('a', column.label), // 添加一个空标签用于显示拖动动画 createElement('span', { 'class': ['virtual'] }) ]) },
세 가지 마우스 이벤트 중 첫 번째 매개변수가 이벤트 객체, 두 번째 매개변수가 헤더 객체입니다.
해당 처리 함수에서 해당 헤더 요소 첨자 인덱스는 columnKey를 통해 얻을 수 있습니다.
빈 라벨 드래그하는 동안 애니메이션을 표시하는 데 사용됩니다(점선)
4. 이벤트 처리
마우스를 누르면 시작 열이 기록됩니다. 마우스를 떼면 끝 열이 기록됩니다. 드래그 방향은 둘 사이의 차이를 기반으로 계산됩니다.
그런 다음 헤더 데이터는 시작 열과 끝 열의 위치에 따라 재정렬되어 열 드래그를 실현합니다.
드래깅 프로세스의 처리 기능은 다음과 같습니다.
// 按下鼠标开始拖动 handleMouseDown (e, column) { this.dragState.dragging = true this.dragState.start = parseInt(column.columnKey) // 给拖动时的虚拟容器添加宽高 let table = document.getElementsByClassName('w-table')[0] let virtual = document.getElementsByClassName('virtual') for (let item of virtual) { item.style.height = table.clientHeight - 1 + 'px' item.style.width = item.parentElement.parentElement.clientWidth + 'px' } }, // 鼠标放开结束拖动 handleMouseUp (e, column) { this.dragState.end = parseInt(column.columnKey) // 记录起始列 this.dragColumn(this.dragState) // 初始化拖动状态 this.dragState = { start: -1, end: -1, move: -1, dragging: false, direction: undefined } }, // 拖动中 handleMouseMove (e, column) { if (this.dragState.dragging) { let index = parseInt(column.columnKey) // 记录起始列 if (index - this.dragState.start !== 0) { this.dragState.direction = index - this.dragState.start < 0 ? 'left' : 'right' // 判断拖动方向 this.dragState.move = parseInt(column.columnKey) } else { this.dragState.direction = undefined } } else { return false } }, // 拖动易位 dragColumn ({start, end, direction}) { let tempData = [] let left = direction === 'left' let min = left ? end : start - 1 let max = left ? start + 1 : end for (let i = 0; i < this.tableHeader.length; i++) { if (i === end) { tempData.push(this.tableHeader[start]) } else if (i > min && i < max) { tempData.push(this.tableHeader[ left ? i - 1 : i + 1 ]) } else { tempData.push(this.tableHeader[i]) } } this.tableHeader = tempData },
5. 드래그 중 점선 효과
이 과정에서 mousemove 이벤트를 통해 현재 열의 헤더 상태가 변경되고
그런 다음 해당 클래스가 headerCellClassName
headerCellClassName ({column, columnIndex}) { return (columnIndex - 1 === this.dragState.move ? `darg_active_${this.dragState.direction}` : '') }
의 도움으로 동적으로 수정됩니다. 헤더 셀
직접 작성한 전체 스타일을 게시하세요(sass를 다음과 같이 사용). 컴파일 도구):
<style lang="scss"> .w-table { .el-table th { padding: 0; .virtual{ position: fixed; display: block; width: 0; height: 0; margin-left: -10px; z-index: 99; background: none; border: none; } &.darg_active_left { .virtual { border-left: 2px dotted #666; } } &.darg_active_right { .virtual { border-right: 2px dotted #666; } } } .thead-cell { padding: 0; display: inline-flex; flex-direction: column; align-items: left; cursor: pointer; overflow: initial; &:before { content: ""; position: absolute; top: 0; left: 0; bottom: 0; right: 0; } } &.w-table_moving { .el-table th .thead-cell{ cursor: move !important; } .el-table__fixed { cursor: not-allowed; } } }
6. 상위 구성 요소 호출
<template> <p> <wTable :data="tableData" :header="tableHeader" :option="tableOption"> <el-table-column slot="fixed" fixed prop="date" label="日期" width="150"> </el-table-column> </wTable> </p> </template> <script> import wTable from '@/components/w-table.vue' export default { name: 'Table', data () { return { tableOption: { border: true, maxHeight: 500 }, tableHeader: [{ prop: 'name', label: '姓名', sortable: true, sortMethod: this.handleNameSort }, { prop: 'province', label: '省份', minWidth: '120' }, { prop: 'city', label: '市区', minWidth: '120' }, { prop: 'address', label: '地区', minWidth: '150' }, { prop: 'zip', label: '邮编', minWidth: '120' }], tableData: [{ date: '2016-05-03', name: '王小虎', province: '上海', city: '普陀区', address: '上海市普陀区金沙江路 1518 弄', zip: 200333 }, { date: '2016-05-02', name: '王小虎', province: '上海', city: '普陀区', address: '上海市普陀区金沙江路 1518 弄', zip: 200333 }, { date: '2016-05-04', name: '王小虎', province: '上海', city: '普陀区', address: '上海市普陀区金沙江路 1518 弄', zip: 200333 }, { date: '2016-05-01', name: '王小虎', province: '上海', city: '普陀区', address: '上海市普陀区金沙江路 1518 弄', zip: 200333 }, { date: '2016-05-08', name: '王小虎', province: '上海', city: '普陀区', address: '上海市普陀区金沙江路 1518 弄', zip: 200333 }, { date: '2016-05-06', name: '王小虎', province: '上海', city: '普陀区', address: '上海市普陀区金沙江路 1518 弄', zip: 200333 }] } }, methods: { handleNameSort () { console.log('handleNameSort') } }, components: { wTable } } </script>
믿으세요. 이 기사의 사례를 읽은 후, 더 흥미로운 정보를 보려면 PHP 중국어의 다른 관련 기사를 주목하세요. 웹사이트!
추천 자료:
위 내용은 Element-UI Table을 사용하여 드래그 앤 드롭 기능 구현의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!