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

Vue?結(jié)合Sortablejs實(shí)現(xiàn)table行排序功能

 更新時(shí)間:2022年10月26日 11:38:02   作者:馬永猛  
在一個(gè)列表展示頁(yè)面上,使用了表格組件,原有組件本身不支持拖拽功能,需求要求在列表的基礎(chǔ)上支持行拖拽排序,因此引入了www.sortablejs.com插件,接下來(lái)通過(guò)本文給大家講解Vue?結(jié)合Sortablejs實(shí)現(xiàn)table行排序功能,需要的朋友可以參考下

Sortable.js是一款輕量級(jí)的拖放排序列表的js插件(雖然體積小,可是功能很強(qiáng)大)

官方Demo:http://rubaxa.github.io/Sortable/

場(chǎng)景

在一個(gè)列表展示頁(yè)面上,使用了表格組件,原有組件本身不支持拖拽功能,需求要求在列表的基礎(chǔ)上支持行拖拽排序。因此引入了www.sortablejs.com插件。

問(wèn)題

引入Sortablejs后剛開(kāi)始都很順利,效果的拖拽基本功能效果已實(shí)現(xiàn)。代碼如下

const tbody = this.$refs.Scheduling.querySelectorAll('.ant-table-tbody') // 元素選擇器名稱(chēng)根據(jù)實(shí)際內(nèi)容替換
Sortable.create(tbody[0]) //具體Sortablejs的api文檔可查看官網(wǎng)

下一步就是保存數(shù)據(jù)
但是在保存數(shù)據(jù)的時(shí)候才發(fā)現(xiàn),數(shù)據(jù)并沒(méi)有修改,還是原來(lái)的數(shù)據(jù),接下來(lái)就來(lái)處理數(shù)據(jù)排序的問(wèn)題,經(jīng)查看Sortablejs文檔引入了onEnd方法,也可用onUpdate方法
代碼修改如下

 const tbody = this.$refs.Scheduling.querySelectorAll('.ant-table-tbody') // 元素選擇器名稱(chēng)根據(jù)實(shí)際內(nèi)容替換
  const _this = this
    Sortable.create(tbody[0], {
      onEnd({ newIndex, oldIndex }) {
      const currRow = _this.databases.splice(oldIndex, 1)[0]
      _this.databases.splice(newIndex, 0, currRow)
      }
    })

修改完之后本以為可以了,就去調(diào)試一下,就出現(xiàn)了比較詭異的問(wèn)題。A和B拖拽交換位置之后,B和A又神奇的換回去了,整體都亂套了!很奇怪。
經(jīng)查看資料才發(fā)現(xiàn)
Vue的實(shí)現(xiàn)原理,在Vue2.0之前是通過(guò)defineProperty依賴(lài)注入和跟蹤的方式實(shí)現(xiàn)雙向綁定。針對(duì)v-for數(shù)組指令,如果指定了唯一的Key,則會(huì)通過(guò)高效的Diff算法計(jì)算出數(shù)組內(nèi)元素的差異,進(jìn)行最少的移動(dòng)或刪除操作。而Vue2.0之后在引入了Virtual Dom之后,Children元素的Dom Diff算法和前者其實(shí)是相似的,唯一的區(qū)別就是,2.0之前Diff直接針對(duì)v-for指令的數(shù)組對(duì)象,2.0之后則針對(duì)Virtual Dom。DOM Diff算法在這里不再贅述,這里解釋的比較清楚virtual-dom diff算法
假設(shè)我們的列表元素?cái)?shù)組是[‘A','B','C','D']
渲染出來(lái)后的DOM節(jié)點(diǎn)是[$A,$B,$C,$D]
那么Virtual Dom對(duì)應(yīng)的結(jié)構(gòu)就是[{elm:$A,data:'A'},
{elm:$B,data:'B'},
{elm:$C,data:'C'},
{elm:$D,data:'D'}]
假設(shè)拖拽排序之后,真實(shí)的DOM變?yōu)閇$B,$A,$C,$D]
此時(shí)我們只操作了真實(shí)DOM,改編了它的位置,而Virtual Dom的結(jié)構(gòu)并沒(méi)有改變,依然是[{elm:$A,data:'A'},
{elm:$B,data:'B'},
{elm:$C,data:'C'},
{elm:$D,data:'D'}]
此時(shí)我們把列表元素也按照真實(shí)DOM排序后變成[‘B','A','C','D']
這時(shí)候根據(jù)Diff算法,計(jì)算出的Patch為,VNode前兩項(xiàng)是同類(lèi)型的節(jié)點(diǎn),所以直接更新,即把$A節(jié)點(diǎn)更新成$B,把$B節(jié)點(diǎn)更新成$A,真實(shí)DOM又變回了[$A,$B,$C,$D]
所以就出現(xiàn)了拖拽之后又被Patch算法更新了一次的問(wèn)題,操作路徑可以簡(jiǎn)單理解為
拖拽移動(dòng)真實(shí)DOM -> 操作數(shù)據(jù)數(shù)組 -> Patch算法再更新真實(shí)DOM
根本原因
根本原因是Virtual DOM和真實(shí)DOM之間出現(xiàn)了不一致。
所以在Vue2.0以前,因?yàn)闆](méi)有引入Virtual DOM,這個(gè)問(wèn)題是不存在的。
在使用Vue框架的時(shí)候要盡量避免直接操作DOM

最后修改代碼如下

 onEnd({ newIndex, oldIndex }) {
         const currRowdom = tbody[0].children[newIndex]
         const oldRowdom = tbody[0].children[oldIndex]
         tbody[0].removeChild(currRowdom)
         if (newIndex > oldIndex) {
          tbody[0].insertBefore(currRowdom, oldRowdom)
        } else {
          tbody[0].insertBefore(currRowdom, oldRowdom.nextSibling)
        }

        const currRow = _this.databases.splice(oldIndex, 1)[0]
        _this.databases.splice(newIndex, 0, currRow)
        }

到此這篇關(guān)于Vue 結(jié)合Sortablejs實(shí)現(xiàn)table行排序 的文章就介紹到這了,更多相關(guān)vue table行排序 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論