首頁 web前端 js教程 使用Element-UI Table實現拖曳功能

使用Element-UI Table實現拖曳功能

Jun 08, 2018 am 11:17 AM
element table ui 拖曳

這次帶給大家使用Element-UI Table實現拖曳功能,使用Element-UI Table實現拖曳功能的注意事項有哪些,以下就是實戰案例,一起來看一下。

Element-UI 的Table 元件很強大,但是我們的需求更強大...

簡單粗暴的來一發效果圖:

一、資料驅動

傳統的拖曳效果,都是基於透過mousedown、mousemove、mouseup 事件來修改刪減dom 節點

但Vue 是資料驅動的前端框架,開發時應盡量避免操作dom

而且Element-UI 的Table 元件封裝得很嚴謹,直接操作dom 很容易產生不可預期的bug

所以我的核心想法就是:透過一個陣列渲染表頭(列),然後修改這個陣列的順序,從而修改列表的列排序

template 部分:

 <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>
登入後複製

上面的data 是清單資料集合,option 是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

綁定了一個函數,動態為表頭單元格新增class,從而實現拖曳中的虛線效果。

2. column-key

綁定為header 陣列的index,用於確定需要修改的header 元素下標

3. render-header

表頭渲染函數,使用以新增自訂方法,以監聽mousemove 等相關事件 

二、記錄拖曳狀態

拖曳過程中需要記錄幾個關鍵參數:

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

另外父元素傳入了一個表頭資料header,但拖曳完成後會修改這個資料

在子元件中直接修改父元素的資料是不建議的,所以這裡初始化了一個tableHeader 用來託管表頭資料header

但為了讓header 修改時,tableHeader 也能回應修改,就得新增一個監視器watch

 watch: {
 header (val, oldVal) {
  this.tableHeader = val
 }
 }
登入後複製

三、自訂表頭

#Element-UI 的Table 元件為了實作【拖曳邊框以修改列寬】的功能,沒有將mousemove、mouseup、mousedown 這三個事件暴露出來

所以需要自訂表頭,並手動新增滑鼠事件的處理函數,這就需要用到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']
   })
  ])
 },
登入後複製

三個滑鼠事件中,第一個參數是事件對象,第二個是表頭物件

在對應的處理函數中,可以透過 column.columnKey 取得到對應的表頭元素下標index

空標籤 用來顯示拖曳時的動畫(虛線)

四、事件處理

按下滑鼠時,記錄下起始列。滑鼠抬起時,記錄下結束列。根據二者之差計算出拖曳的方向。

然後根據起始列和結束列的位置,將表頭資料重新排序,從而實現列的拖曳

拖曳過程的處理函數如下:

// 按下鼠标开始拖动
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
},
登入後複製

五、虛線效果

在拖曳過程中,透過mousemove 事件,改變目前列的表頭狀態

然後借助headerCellClassName 動態修改其class

headerCellClassName ({column, columnIndex}) {
 return (columnIndex - 1 === this.dragState.move ? `darg_active_${this.dragState.direction}` : &#39;&#39;)
}
登入後複製

這個class 會加入到表頭儲存格 上,透過這個class 給上面的空標籤 加虛線即可

貼一下我自己寫的完整樣式(使用了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;
 }
 }
}
登入後複製

#六、父元件呼叫

<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中文網其它相關文章!

推薦閱讀:

progressbar元件實戰案例解析

如何最佳化Vue專案

以上是使用Element-UI Table實現拖曳功能的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

element.style怎麼修改 element.style怎麼修改 Nov 24, 2023 am 11:15 AM

element.style修改元素的方法:1、修改元素的背景顏色;2、修改元素的字體大小;3、修改元素的邊框樣式;4、修改元素的字體樣式;5、修改元素的水平對齊方式。詳細介紹:1、修改元素的背景顏色,其語法為「document.getElementById("myElement").style.backgroundColor = "red";」;2、修改元素的字體大小等等。

如何使用 JavaScript 實作圖片的拖曳縮放功能? 如何使用 JavaScript 實作圖片的拖曳縮放功能? Oct 27, 2023 am 09:39 AM

如何使用JavaScript實作圖片的拖曳縮放功能?在現代web開發中,實現圖片的拖曳和縮放是常見的需求。透過使用JavaScript,我們可以輕鬆地為圖片添加拖曳和縮放功能,提供更好的使用者體驗。在本篇文章中,將介紹如何使用JavaScript來實現此功能,以及附有具體的程式碼範例。 HTML結構首先,我們需要一個基本的HTML結構來展示圖片,並為圖片增加

艾爾登法環ui怎麼一直顯示 艾爾登法環ui怎麼一直顯示 Mar 11, 2024 pm 04:31 PM

在艾爾登法環中這款遊戲的ui頁面在一段時間以後是會自動進行隱藏的,有很多玩家不知道ui怎麼一直顯示,玩家可以在顯示以及聲音配置中選擇其中的量表顯示配置,點擊開啟即可。艾爾登法環ui怎麼一直顯示1、首先我們進入主選單後,點選【系統配置】。 2.在【顯示及聲音配置】介面,選擇其中的量表顯示配置。 3.點擊開啟即可完成。

Vue 中實現拖曳選取及放置的技巧及最佳實踐 Vue 中實現拖曳選取及放置的技巧及最佳實踐 Jun 25, 2023 am 10:13 AM

Vue是一款流行的JavaScript框架,適合用於建立單頁面應用程式(SPA)。其支援透過指令和元件等方式實現拖曳選取及放置的功能,為使用者提供了更好的互動體驗。本文將介紹在Vue中實現拖曳選取及放置的技巧及最佳實務。拖曳指令Vue提供了一個v-draggable指令,可以輕鬆實現拖曳效果。該指令可以被應用於任何元素上,並且可以自訂拖曳的樣

Vue 常見的 UI 元件庫有哪些? Vue 常見的 UI 元件庫有哪些? Jun 11, 2023 am 11:47 AM

Vue是一款流行的JavaScript框架,它使用元件化的方式來建立Web應用程式。在Vue生態系統中,有許多UI元件庫可以幫助您快速建立漂亮的介面,並提供豐富的功能和互動效果。在本文中,我們將介紹一些常見的VueUI元件庫。 ElementUIElementUI是一款由餓了麼團隊開發的Vue元件庫,它為開發人員提供了一組優雅,

如何使用Vue實現拖曳排序特效 如何使用Vue實現拖曳排序特效 Sep 20, 2023 pm 03:01 PM

如何使用Vue實作拖曳排序特效Vue.js是一款流行的JavaScript框架,它能夠幫助我們建立互動性強的前端應用程式。在Vue中,我們可以輕鬆實現拖曳排序特效,讓使用者可以透過拖曳元素的方式進行資料排序。本文將介紹如何使用Vue實作拖曳排序特效,並提供具體的程式碼範例。首先,我們需要建立一個Vue的實例,並定義一個陣列來儲存要排序的資料。在範例中,我們將

Vue實戰技巧:使用v-on指令處理滑鼠拖曳事件 Vue實戰技巧:使用v-on指令處理滑鼠拖曳事件 Sep 15, 2023 am 08:24 AM

Vue實戰技巧:使用v-on指令處理滑鼠拖曳事件前言:Vue.js是一個流行的JavaScript框架,它的簡潔易用和靈活性使得它成為了眾多開發者的首選。在Vue應用程式開發中,處理使用者互動事件是必不可少的技能。本文將介紹如何使用Vue的v-on指令來處理滑鼠拖曳事件,並提供具體的程式碼範例。建立Vue實例:首先,在HTML檔案中引入Vue.js的庫檔:&

兩位Google華人研究員發布首個純視覺「行動UI理解」模型,四大任務刷新SOTA 兩位Google華人研究員發布首個純視覺「行動UI理解」模型,四大任務刷新SOTA Apr 12, 2023 pm 04:40 PM

對AI來說,「玩手機」可不是一件易事,光是辨識各種使用者介面(user interface, UI)就是一大難題:不光要辨識出各個元件的類型,還要根據其使用的符號、位置來判斷組件的功能。對行動裝置UI的理解,能夠幫助實現各種人機互動任務,例如UI自動化等。先前的工作對行動UI的建模通常依賴螢幕的視圖層次信息,直接利用了UI的結構數據,並藉此繞過了從螢幕像素開始對組件進行識別的難題。不過並不是所有的場景下都有可用的視圖層次,這種方法通常會因為物件描述的缺失或結構資訊的錯位而輸出錯誤結果,所以儘管使

See all articles