由於當前表格較為複雜,其中包含較多合併單元格,所以拖拽不大好處理,於是使用簡單的上移下移按鈕來替代。表格採用的是element-ui的el-table實現的。用於展示的數據是一個數組,經過合併單元格的方法處理,展現效果為上圖所示。而上移、下移是基於整體項目的上移下移。vue中無需操作dom節點僅修改數據就可以達到頁面的處理效果,所以上移、下移只需要修改這個用於展示的數組的數據即可。
大概思路:
如果,直接基於數組中的數據進行處理,邏輯上會較為複雜,所以可以考慮將相同項目的數據作為一個整體,調整順序後,重新轉換為分散的數據。
具體代碼:
/** * 根據項目id轉換二維數組 * @param sourceArray 源數組 項目明細數組 * @param targetItemId 目標項目id */ convertItemArray(sourceArray, targetItemId) { // 目標數組 const targetArray = [] // 項目順序數組 用於保存項目順序 const itemOrder = [] // 項目map 用於數據分類 const itemMap = {} // 傳入源數組有值 if (sourceArray && sourceArray.constructor === Array && sourceArray.length) { // 遍歷原數組 sourceArray.forEach(item => { const itemId = item.itemId // 項目順序數組中不存在該項目時 添加到數組中 if (itemOrder.indexOf(itemId) === -1) { itemOrder.push(itemId) } // 項目id匹配目標項目id if (targetItemId === itemId) { // 獲取目標項目id對應的下標值 this.curItemIndex = itemOrder.length - 1 } // 臨時項目數組 let tempItemArray = [] // 如果項目中存在數組 則為其賦值 if (itemMap[itemId]) { tempItemArray = itemMap[itemId] } // 將項目添加到數組中 tempItemArray.push(item) // 將數組添加到map中 itemMap[itemId] = tempItemArray }) } // 項目順序數組有值 if (itemOrder && itemOrder.length) { // 遍歷項目順序 itemOrder.forEach(itemId => { // 根據項目id取出項目數組 const tempItemArray = itemMap[itemId] // 添加到目標數組中 targetArray.push(tempItemArray) }) } // 返回目標數組 return targetArray }, /** * 將二維數組轉換為一維數組(項目數組轉換為項目明細數組) */ convertItemDetailArray(sourceArray) { // 目標數組 const targetArray = [] // 判斷不為空 if (sourceArray && sourceArray.constructor === Array && sourceArray.length) { for (let i = 0; i < sourceArray.length; i++) { const itemArray = sourceArray[i] // 判斷當前元素是數組 if (itemArray && itemArray.constructor === Array) { // 當前是最後一項時 if (i === sourceArray.length - 1) { // 計算最後一項下標值 this.lastProjectIndex = targetArray.length } for (let j = 0; j < itemArray.length; j++) { const item = itemArray[j] // 重置排序號 item.itemOrder = i // 添加元素到目標數組中 targetArray.push(item) } } } } // 返回目標數組 return targetArray }, /** * 數組元素交換位置 * @param {array} arr 數組 * @param {number} index1 添加項目的位置 * @param {number} index2 刪除項目的位置 * index1和index2分別是兩個數組的索引值,即是兩個要交換元素位置的索引值,如1,5就是數組中下標為1和5的兩個元素交換位置 */ swapArray(arr, index1, index2) { arr[index1] = arr.splice(index2, 1, arr[index1])[0] return arr }, /*** 下移項目* @param {Object} index */ downProject(index) { // 獲取項目id const itemId = this.itemDetailList[index].itemId // 先根據項目id轉換二維數組 並給項目數組下標賦值 const itemArray = this.convertItemArray(this.itemDetailList, itemId) // 下標值大於等於0 if (this.curItemIndex >= 0) { // 下移 交換位置 this.swapArray(itemArray, this.curItemIndex, this.curItemIndex + 1) } // 轉換回一維數組 this.itemDetailList = this.convertItemDetailArray(itemArray) // 項目合併單元格 this.merage() // 評價方法合併單元格 this.mergeIndexArr = this.getMergeArr(this.itemDetailList, 'checkMethod') }, /** * 上移項目 * @param {Object} index */ upProject(index) { // 獲取項目id const itemId = this.itemDetailList[index].itemId // 先根據項目id轉換二維數組 並給項目數組下標賦值 const itemArray = this.convertItemArray(this.itemDetailList, itemId) // 下標值-1 大於等於0 if (this.curItemIndex - 1 >= 0) { // 上移 交換位置 this.swapArray(itemArray, this.curItemIndex - 1, this.curItemIndex) } // 轉換回一維數組 並且重置itemOrder 項目排序號 this.itemDetailList = this.convertItemDetailArray(itemArray) // 項目合併單元格 this.merage() // 評價方法合併單元格 this.mergeIndexArr = this.getMergeArr(this.itemDetailList, 'checkMethod') },