最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

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

用這3個屬性實(shí)時的去更新排序

  • 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ù)出錯,沒有啥實(shí)際用途) tableData是表格渲染的數(shù)據(jù) arr是點(diǎn)擊下拉異步請求的數(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)渲染出來了 ,因?yàn)橄吕臄?shù)據(jù)要異步去獲取,所以在element提供的下拉事件里面去請求數(shù)據(jù),這里去獲取子級的數(shù)據(jù),并給maps賦值,利用遞歸,把數(shù)據(jù)平鋪、組裝。

//點(diǎn)擊下拉圖標(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('沒有更多消息了');
                }
            })
        },

定義的行拖拽方法,因?yàn)榕判蚴怯玫?個屬性去排序的,所以有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é)點(diǎn)數(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)實(shí)現(xiàn)了,就沒有去深入的挖掘,可能會有問題,但是隔的時間太久了,基本忘光了。

總結(jié)

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

相關(guān)文章

  • vue項(xiàng)目中解決 IOS + H5 滑動邊界橡皮筋彈性效果(解決思路)

    vue項(xiàng)目中解決 IOS + H5 滑動邊界橡皮筋彈性效果(解決思路)

    最近遇到一個問題,我們在企業(yè)微信中的 H5 項(xiàng)目中需要用到table表格(支持懶加載 上劃加載數(shù)據(jù)),但是他們在鎖頭、鎖列的情況下,依舊會出現(xiàn)邊界橡皮筋效果,這篇文章主要介紹了vue項(xiàng)目中解決 IOS + H5 滑動邊界橡皮筋彈性效果,需要的朋友可以參考下
    2023-02-02
  • vue寫一個組件

    vue寫一個組件

    這篇文章主要介紹了vue組寫一個組件,需要的朋友可以參考下
    2018-04-04
  • vue中巧用三元表達(dá)式解析

    vue中巧用三元表達(dá)式解析

    這篇文章主要介紹了vue中巧用三元表達(dá)式解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • mpvue跳轉(zhuǎn)頁面及注意事項(xiàng)

    mpvue跳轉(zhuǎn)頁面及注意事項(xiàng)

    這篇文章主要介紹了mpvue跳轉(zhuǎn)頁面及注意事項(xiàng)的相關(guān)資料,需要的朋友可以參考下
    2018-08-08
  • 前端H5微信支付寶支付實(shí)現(xiàn)方法(uniapp為例)

    前端H5微信支付寶支付實(shí)現(xiàn)方法(uniapp為例)

    最近上線一個項(xiàng)目,手機(jī)網(wǎng)站進(jìn)行調(diào)起支付寶App支付,做起來還是滿順手的,在此做個記錄,這篇文章主要給大家介紹了關(guān)于前端H5微信支付寶支付實(shí)現(xiàn)方法的相關(guān)資料,需要的朋友可以參考下
    2024-04-04
  • vue項(xiàng)目如何全局修改el-button樣式

    vue項(xiàng)目如何全局修改el-button樣式

    這篇文章主要介紹了vue項(xiàng)目如何全局修改el-button樣式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • vue中的.capture和.self區(qū)分及初步理解

    vue中的.capture和.self區(qū)分及初步理解

    這篇文章主要介紹了vue中的.capture和.self區(qū)分及初步理解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue父組件值變化但子組件不刷新的三種解決方案

    vue父組件值變化但子組件不刷新的三種解決方案

    父組件傳遞給子組件的數(shù)據(jù),如果是一個復(fù)雜對象(例如一個數(shù)組或?qū)ο螅?那么子組件只會監(jiān)聽對象的引用而不是對象的內(nèi)容,這意味著當(dāng)對象的內(nèi)容發(fā)生變化時,子組件不會更新,本文給大家介紹了vue子組件不刷新的三種解決方案,需要的朋友可以參考下
    2024-03-03
  • 淺談Vue組件及組件的注冊方法

    淺談Vue組件及組件的注冊方法

    本文主要介紹了淺談Vue組件及組件的注冊方法,詳細(xì)的介紹了什么是組件,及其組件注冊的兩種方式(全局和局部),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • Vue使用pdf.js和docx-preview實(shí)現(xiàn)docx和pdf的在線預(yù)覽

    Vue使用pdf.js和docx-preview實(shí)現(xiàn)docx和pdf的在線預(yù)覽

    這篇文章主要為大家詳細(xì)介紹了在Vue中使用pdf.js和docx-preview實(shí)現(xiàn)docx和pdf的在線預(yù)覽的相關(guān)知識,文中的示例代碼講解詳細(xì),需要的可以參考下
    2025-03-03

最新評論

监利县| 土默特右旗| 新泰市| 蒙阴县| 四平市| 元谋县| 莒南县| 张北县| 全南县| 安泽县| 石景山区| 阿尔山市| 盖州市| 梅河口市| 敦化市| 金乡县| 绩溪县| 乃东县| 织金县| 广州市| 百色市| 德化县| 昭平县| 哈密市| 枝江市| 营山县| 灌南县| 柘荣县| 凤冈县| 繁峙县| 井研县| 鲁甸县| 中山市| 如东县| 图们市| 平原县| 金乡县| 惠安县| 来安县| 广州市| 南安市|