Maison > interface Web > js tutoriel > Utilisez Element-UI Table pour implémenter la fonction glisser-déposer

Utilisez Element-UI Table pour implémenter la fonction glisser-déposer

php中世界最好的语言
Libérer: 2018-06-08 11:17:20
original
6391 Les gens l'ont consulté

Cette fois, je vais vous présenter comment utiliser Element-UI Table pour implémenter la fonction glisser-déposer. Quelles sont les précautions à prendre pour utiliser Element-UI Table pour implémenter la fonction glisser-déposer ? un regard.

Le composant Table d'Element-UI est très puissant, mais nos besoins sont encore plus puissants...

Un rendu simple et brut :

1. Basés sur les données

Les effets de glisser traditionnels sont tous basés sur la modification via les événements mousedown, mousemove, mouseup Supprimez le nœud dom.

Mais Vue est un framework frontal basé sur les données. Vous devriez essayer d'éviter d'utiliser le dom pendant le développement

Et le composant Table d'Element-UI est très rigoureusement encapsulé, il l'est donc. facile d'utiliser directement le dom. Générer des bugs imprévisibles

Mon idée principale est donc : Rendre l'en-tête du tableau (colonne) à travers un tableau, puis modifier l'ordre du tableau, modifiant ainsi le tri des colonnes de la liste

partie modèle :

 <p class="w-table" :class="{&#39;w-table_moving&#39;: dragState.dragging}">
 <el-table :data="data"
  :border="option.border"
  :height="option.height"
  :max-height="option.maxHeight"
  :style="{ width: parseInt(option.width)+&#39;px&#39; }"
  :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>
Copier après la connexion

Les données ci-dessus sont la collecte de données de la liste, l'option est l'élément de configuration du composant Table et le header est la collection de données d'en-tête de table, qui est transmise depuis le composant parent

props: {
 data: {
  default: function () {
  return []
  },
  type: Array
 },
 header: {
  default: function () {
  return []
  },
  type: Array
 },
 option: {
  default: function () {
  return {}
  },
  type: Object
 }
 }
Copier après la connexion

Les éléments de configuration peuvent être supprimés selon l'API d'Element-UI

Mais plusieurs paramètres sont requis à l'intérieur du composant :

1. header-cell -class-name

lie une fonction pour ajouter dynamiquement une classe à la cellule d'en-tête pour obtenir l'effet de ligne pointillée lors du glissement.

2. column-key

est lié à l'index du tableau d'en-tête, utilisé pour déterminer l'indice de l'élément d'en-tête qui doit être modifié

3. render-header

La fonction de rendu d'en-tête est utilisée pour ajouter des méthodes personnalisées pour surveiller le déplacement de la souris et d'autres événements associés

2. status

Plusieurs paramètres clés doivent être enregistrés lors du processus de glisser :

data () {
 return {
  tableHeader: this.header,
  dragState: {
  start: -1, // 起始元素的 index
  end: -1, // 结束元素的 index
  move: -1, // 移动鼠标时所覆盖的元素 index
  dragging: false, // 是否正在拖动
  direction: undefined // 拖动方向
  }
 }
 }
Copier après la connexion

De plus, l'élément parent passe dans un header data header, mais ces données seront modifiées une fois le glissement terminé

Il n'est pas recommandé de modifier directement les données de l'élément parent dans le composant enfant, donc un tableHeader est initialisé ici pour héberger l'en-tête des données d'en-tête

Mais dans l'ordre pour permettre la modification de l'en-tête, le tableHeader peut également répondre à la modification. Vous devez ajouter une montre de moniteur

 watch: {
 header (val, oldVal) {
  this.tableHeader = val
 }
 }
Copier après la connexion

3. Personnaliser l'en-tête du tableau

Le composant Table d'Element-UI afin d'implémenter la fonction [faites glisser la bordure pour modifier la largeur de la colonne] n'expose pas les trois événements mousemove, mouseup et mousedown

, vous devez donc personnaliser l'en-tête et manuellement ajoutez la fonction de traitement des événements de la souris, qui nécessite l'utilisation de la méthode

renderHeader()

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']
   })
  ])
 },
Copier après la connexion
Parmi les trois événements de la souris, le premier paramètre est l'objet événement , et le deuxième paramètre est l'objet d'en-tête

dans le traitement correspondant. Dans la fonction, vous pouvez utiliser

column.columnKey pour obtenir l'index d'indice de l'élément d'en-tête correspondant

l'étiquette vide est utilisée. Afficher l'animation lors du glissement (ligne pointillée)

4. Traitement des événements

Quand la souris est enfoncée, enregistrez la colonne de départ. Lorsque la souris est levée, la colonne de fin est enregistrée. La direction de la traînée est calculée en fonction de la différence entre les deux.

Ensuite, les données d'en-tête sont réorganisées en fonction des positions de la colonne de début et de la colonne de fin, réalisant ainsi le glissement de colonne

La fonction de traitement du processus de glissement est la suivante :

// 按下鼠标开始拖动
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 ? &#39;left&#39; : &#39;right&#39; // 判断拖动方向
  this.dragState.move = parseInt(column.columnKey)
 } else {
  this.dragState.direction = undefined
 }
 } else {
 return false
 }
},

// 拖动易位
dragColumn ({start, end, direction}) {
 let tempData = []
 let left = direction === &#39;left&#39;
 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
},
Copier après la connexion

5. Effet de ligne pointillée

Pendant le processus de glissement, utilisez l'événement mousemove pour modifier l'état de l'en-tête de la colonne actuelle

puis utilisez

headerCellClassName Modifier dynamiquement sa classe

headerCellClassName ({column, columnIndex}) {
 return (columnIndex - 1 === this.dragState.move ? `darg_active_${this.dragState.direction}` : &#39;&#39;)
}
Copier après la connexion
Cette classe sera ajoutée à la cellule d'en-tête, et l'étiquette vide au-dessus Ajoutez simplement une ligne pointillée

Publiez le style complet que j'ai écrit (en utilisant sass comme outil de compilation) :

<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;
 }
 }
}
Copier après la connexion

6. Parent appel de composant

<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>
Copier après la connexion
Je pense que vous maîtrisez la méthode après avoir lu le cas dans cet article. Pour des informations plus intéressantes, veuillez prêter attention aux autres articles connexes sur le site Web chinois de php !

Lecture recommandée :

Analyse de cas pratique du composant Progressbar

Comment optimiser le projet Vue

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal