Dieses Mal werde ich Ihnen vorstellen, wie Sie Element-UI Table zum Implementieren der Drag-and-Drop-Funktion verwenden. Welche Vorsichtsmaßnahmen sind für die Verwendung von Element-UI-Table zum Implementieren der Drag-and-Drop-Funktion zu beachten? sehen.
Die Tabellenkomponente von Element-UI ist sehr leistungsfähig, aber unsere Anforderungen sind noch leistungsfähiger...
Ein einfaches und grobes Rendering:
1. Datengesteuert
Traditionelle Drag-Effekte basieren auf Modifikationen durch Mousedown, Mousemove, Mouseup Dom-Knoten löschen
Vue ist jedoch ein datengesteuertes Front-End-Framework. Sie sollten versuchen, den Dom während der Entwicklung nicht zu bedienen.
Und die Tabellenkomponente von Element-UI ist sehr streng gekapselt, sodass es einfach ist um den Dom direkt zu betreiben. Unvorhersehbare Fehler erzeugen
Meine Kernidee ist also: Rendern Sie den Tabellenkopf (Spalte) durch ein Array und ändern Sie dann die Reihenfolge des Arrays, wodurch die Spaltensortierung der Liste
Vorlagenteil:
<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>
Die oben genannten Daten sind die Listendatensammlung, die Option ist das Konfigurationselement der Tabellenkomponente und der Header ist der Sammlung von Tabellenkopfdaten, die von der übergeordneten Komponente übergeben werden
props: { data: { default: function () { return [] }, type: Array }, header: { default: function () { return [] }, type: Array }, option: { default: function () { return {} }, type: Object } }
Konfigurationselemente können gemäß der Element-UI-API gelöscht werden
Innerhalb der Komponente sind jedoch mehrere Parameter erforderlich:
1. Header-Cell-Class-Name
ist an eine Funktion gebunden, um der Header-Zelle dynamisch eine Klasse hinzuzufügen, um beim Ziehen den gepunkteten Linieneffekt zu erzielen.
2. Spaltenschlüssel
ist an den Index des Header-Arrays gebunden und wird verwendet, um den Index des Header-Elements zu bestimmen, das geändert werden muss
3. render-header
Die Header-Rendering-Funktion wird verwendet, um benutzerdefinierte Methoden zur Überwachung von Mausbewegungen und anderen zugehörigen Ereignissen hinzuzufügen
2 Status
Während des Ziehvorgangs müssen mehrere Schlüsselparameter aufgezeichnet werden:
data () { return { tableHeader: this.header, dragState: { start: -1, // 起始元素的 index end: -1, // 结束元素的 index move: -1, // 移动鼠标时所覆盖的元素 index dragging: false, // 是否正在拖动 direction: undefined // 拖动方向 } } }
Darüber hinaus übergibt das übergeordnete Element einen Header-Datenheader, diese Daten werden jedoch nach dem geändert Das Ziehen ist abgeschlossen
Es wird nicht empfohlen, die Daten des übergeordneten Elements in der untergeordneten Komponente direkt zu ändern. Daher wird hier ein tableHeader initialisiert, um den Header-Datenkopf zu hosten
Aber um dies zu ermöglichen Der zu ändernde Header kann auch auf die Änderung reagieren. Fügen Sie eine Monitorüberwachung hinzu
3 Passen Sie den Header an
Die Tabellenkomponente von Element-UI Um die Funktion von [Ziehen Sie den Rand, um die Spaltenbreite zu ändern] zu realisieren, werden die drei Ereignisse Mousemove, Mouseup und Mousedown nicht angezeigt , daher müssen Sie die Kopfzeile anpassen und die Maus manuell hinzufügen Ereignisverarbeitungsfunktion, die die Verwendung vonrenderHeader() Methode
watch: { header (val, oldVal) { this.tableHeader = val } }
Column.columnKey Den entsprechenden Index des Header-Elements abrufen
Leeres Etikett wird verwendet, um die Animation während des Ziehens anzuzeigen (gepunktete Linie)4. Ereignisverarbeitung
Wenn die Maus gedrückt wird, zeichnen Sie die Startspalte auf. Beim Anheben der Maus wird die Endspalte aufgezeichnet. Die Widerstandsrichtung wird anhand der Differenz zwischen beiden berechnet. Dann werden die Kopfdaten entsprechend der Position der Startspalte und der Endspalte neu angeordnet, wodurch das Spaltenziehen realisiert wird Die Verarbeitungsfunktion des Ziehvorgangs ist wie folgt: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'] }) ]) },
5. Gepunkteter Linieneffekt
Ändern Sie während des Ziehvorgangs den Kopfzeilenstatus der aktuellen Spalte durch das Mousemove-EreignisUnd verwenden Sie dannheaderCellClassName Seine Klasse dynamisch ändern
// 按下鼠标开始拖动 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 },
headerCellClassName ({column, columnIndex}) { return (columnIndex - 1 === this.dragState.move ? `darg_active_${this.dragState.direction}` : '') }
6. Aufruf der übergeordneten Komponente
<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; } } }
Empfohlene Lektüre:
Praxisfallanalyse der Progressbar-Komponente
So optimieren Sie das Vue-Projekt
Das obige ist der detaillierte Inhalt vonVerwenden Sie die Element-UI-Tabelle, um die Drag-and-Drop-Funktion zu implementieren. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!