欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue elementUi+sortable.js實現(xiàn)嵌套表格拖拽問題

 更新時間:2024年06月07日 16:29:08   作者:一杯白水~  
這篇文章主要介紹了vue elementUi+sortable.js實現(xiàn)嵌套表格拖拽問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

vue elementUi+sortable.js嵌套表格拖拽

首先說下項目需求,一個多層嵌套的表格,行可以進(jìn)行拖拽排序,但不能跨主級去拖拽,下拉可以異步獲取數(shù)據(jù),考慮了很久,還是用最熟悉的vue+element來做,但是element沒有拖拽排序的功能,所以在此基礎(chǔ)上加入sortable.js去實現(xiàn)拖拽功能。

后臺返回的排序規(guī)則是 每個數(shù)據(jù)都帶有3個屬性 id next prev 

用這3個屬性實時的去更新排序

  • id表示這一條數(shù)據(jù)的id
  • next表示下一條數(shù)據(jù)的id
  • prev表示上一條數(shù)據(jù)的id

html部分

data部分

 flattArray:[],
 originalData:[],
 tableData: [],
 arr:[],
 maps:new Map()

我這里定義了四個數(shù)組和一個map

flattArray是平鋪的數(shù)據(jù) originalData數(shù)組也是平鋪的數(shù)據(jù)(以防數(shù)據(jù)出錯,沒有啥實際用途) tableData是表格渲染的數(shù)據(jù) arr是點擊下拉異步請求的數(shù)據(jù)

maps是tableData改變后去重新渲染數(shù)據(jù)用的

methods部分

首先我定義了一個方法去深拷貝,這樣改變一個數(shù)據(jù)的時候,其他數(shù)據(jù)不會改變

 //深拷貝
 getNewObject(val) {
     let resObj = JSON.stringify(val);
     return JSON.parse(resObj);
 },

加載頁面從接口 獲取 tableData數(shù)據(jù) 并深拷貝 tableData

getDetails(id){
    axios.get(url).then(res =>{
        if(res.data.code === 0){
           this.tableData = res.data.data
           this.tableData.map( item =>{
             item.hasChildren = true
             delete item.children
           })
           this.flattArray = this.getNewObject(this.tableData)
           this.originalData = this.getNewObject(this.tableData)
         }else{
             this.$message.error('網(wǎng)絡(luò)錯誤');
        }
   }).catch(function (error) {
      this.$message.error('網(wǎng)絡(luò)錯誤');
   });
},

這里表格就已經(jīng)渲染出來了 ,因為下拉的數(shù)據(jù)要異步去獲取,所以在element提供的下拉事件里面去請求數(shù)據(jù),這里去獲取子級的數(shù)據(jù),并給maps賦值,利用遞歸,把數(shù)據(jù)平鋪、組裝。

//點擊下拉圖標(biāo)異步加載數(shù)據(jù)
load(tree, treeNode, resolve) {
            this.maps.set(tree.id, { tree, treeNode, resolve })
            axios.get(`url` + tree.id).then(res => {
                if (res.data.code == 0) {
                    this.arr = res.data.data
                    this.arr.map(item => {
                        item.hasChildren = true
                        delete item.children
                        this.flattArray.push(item)
                    })
                    resolve(this.arr)
                    const tree = buildTree(this.flattArray, 1);
                    //組裝tree
                    function buildTree(nodes, parent) {
                        const res = [];
                        for (let item of nodes) {
                            if (item.parentId === parent) {
                                const children = buildTree(nodes, item.id);
                                if (children.length) {
                                    item.children = children;
                                }
                                res.push(item);
                            }
                        }
                        return res;
                    }
                    //平鋪tree
                    let result = [];
 
                    function flatTree(nodes, parentId) {
                        if (!nodes || nodes.length === 0) return [];
                        nodes.forEach(node => {
                            result.push(node);
                            return flatTree(node.children, node.id);
                        });
                    }
                    flatTree(tree, 1);
 
                    this.originalData = result
                    this.getNewObject(this.originalData)
                } else {
                    this.$message.error('沒有更多消息了');
                }
            })
        },

定義的行拖拽方法,因為排序是用的3個屬性去排序的,所以有3種情況去考慮

  • 一是拖動到最上級,這樣prev的值就為空
  • 二是拖動到最下級,next為空
  • 三是正常的拖動,next prev都不為空
 rowDrop() {
            this.$nextTick(() => {
                const tbody = document.querySelector('.el-table__body-wrapper tbody')
                const _this = this
                Sortable.create(tbody, {
                    animation: 300,
                    sort: true,
                    onEnd({
                              oldIndex,
                              newIndex,
                              item
                          }) {
                        const sourceObj = _this.originalData[oldIndex - 1] // 原本的位置
                        const targetObj = _this.originalData[newIndex - 1] // 移動到的位置
                        const frontObj = _this.originalData[newIndex - 2] //移動后位置的上一級
                        const behindObj = _this.originalData[newIndex] //移動后位置的下一級
                        if(sourceObj.parentId != targetObj.parentId) {
                            _this.$message.error("不支持跨級拖動,請拖回原來位置")
                            location.reload();
                            return;
                        }
                        let data = [];
                        if( oldIndex < newIndex ){//向下移動
                            //上一級
                            let predata = {
                                id: targetObj.id,
                                next: sourceObj.id,
                                prev: targetObj.prev
                            }
                            //自己
                            let curdata = {
                                id: sourceObj.id,
                                next: targetObj.next,
                                prev: targetObj.id,
                                groupId: sourceObj.groupId
                            }
                            //下一級
                            let nextdata = null
                            if (behindObj != undefined && sourceObj.parentId == behindObj.parentId) {
                                nextdata = {
                                    id: behindObj.id,
                                    next: behindObj.next,
                                    prev: sourceObj.id
                                }
                            }
                            if(nextdata){
                                data.push(curdata, predata, nextdata)
                            }else{
                                data.push(curdata, predata)
                            }
                            _this.postdata(data, sourceObj.parentId)
                        }else if( oldIndex > newIndex ){//向上移動
                            //上一級
                            let predata = null
                            if (frontObj != undefined && sourceObj.parentId == frontObj.parentId) {
                                predata = {
                                    id: frontObj.id,
                                    next: sourceObj.id,
                                    prev: frontObj.prev
                                }
                            }
                            //自己
                            let curdata = {
                                id: sourceObj.id,
                                next: targetObj.id,
                                prev: targetObj.prev,
                                groupId: sourceObj.groupId
                            }
                            //下一級
                            let nextdata = {
                                id: targetObj.id,
                                next: targetObj.next,
                                prev: sourceObj.id
                            }
 
                            if(predata){
                                data.push(curdata, predata, nextdata)
                            }else{
                                data.push(curdata, nextdata)
                            }
                            _this.postdata(data, sourceObj.parentId)
                        }
                    }
                })
            })
        },

mounted 里面去加載 改變行的方法

 mounted() {
          this.rowDrop()
 },

最后再去動態(tài)的更新數(shù)據(jù)

refreshLoadTree(parentId) {
            // 根據(jù)父級id取出對應(yīng)節(jié)點數(shù)據(jù)
            const {tree, treeNode, resolve} = this.maps.get(parentId)
            this.$set(this.$refs.tableData.store.states.lazyTreeNodeMap, parentId, [])
            if (tree) {
                this.load(tree, treeNode, resolve)
            }
        },

到這里需求已經(jīng)實現(xiàn)了,就沒有去深入的挖掘,可能會有問題,但是隔的時間太久了,基本忘光了。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 使用異步組件優(yōu)化Vue應(yīng)用程序的性能

    使用異步組件優(yōu)化Vue應(yīng)用程序的性能

    這篇文章主要介紹了使用異步組件優(yōu)化Vue應(yīng)用程序的性能,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-04-04
  • vue動態(tài)生成dom并且自動綁定事件

    vue動態(tài)生成dom并且自動綁定事件

    本篇文章主要介紹了vue動態(tài)生成dom并且自動綁定事件,具有一定的參考價值,有興趣的可以了解一下。
    2017-04-04
  • Vuex之module使用方法及場景說明

    Vuex之module使用方法及場景說明

    這篇文章主要介紹了Vuex之module使用方法及場景說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • Vue+Electron打包桌面應(yīng)用(超詳細(xì)完整教程)

    Vue+Electron打包桌面應(yīng)用(超詳細(xì)完整教程)

    這篇文章主要介紹了Vue+Electron打包桌面應(yīng)用超詳細(xì)完整教程,在這大家要記住整個項目的json文件不能有注釋,及時沒報錯也不行,否則運行命令時還是有問題,具體細(xì)節(jié)問題參考下本文詳細(xì)講解
    2024-02-02
  • 使用vue3+TS實現(xiàn)簡易組件庫的全過程

    使用vue3+TS實現(xiàn)簡易組件庫的全過程

    當(dāng)市面上主流的組件庫不能滿足我們業(yè)務(wù)需求的時候,那么我們就有必要開發(fā)一套屬于自己團(tuán)隊的組件庫,下面這篇文章主要給大家介紹了如何使用vue3+TS實現(xiàn)簡易組件庫的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • 詳解無限滾動插件vue-infinite-scroll源碼解析

    詳解無限滾動插件vue-infinite-scroll源碼解析

    這篇文章主要介紹了詳解無限滾動插件vue-infinite-scroll源碼解析,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-05-05
  • vue實現(xiàn)的下拉框功能示例

    vue實現(xiàn)的下拉框功能示例

    這篇文章主要介紹了vue實現(xiàn)的下拉框功能,涉及vue.js數(shù)據(jù)讀取、遍歷、事件響應(yīng)等相關(guān)操作技巧,需要的朋友可以參考下
    2019-01-01
  • vue+webpack 打包文件 404 頁面空白的解決方法

    vue+webpack 打包文件 404 頁面空白的解決方法

    下面小編就為大家分享一篇vue+webpack 打包文件 404 頁面空白的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-02-02
  • vue keep-alive多層級路由支持問題分析

    vue keep-alive多層級路由支持問題分析

    這篇文章主要介紹了vue keep-alive多層級路由支持,在文章開頭給大家介紹了keep-alive使用問題,解決使用keep-alive include屬性問題,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-03-03
  • Vue2和Vue3中常用組件通信用法分享

    Vue2和Vue3中常用組件通信用法分享

    這篇文章主要為大家整理了Vue3的8種和Vue2的12種組件通信的使用方法,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Vue有一定的幫助,值得收藏
    2023-04-04

最新評論