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)文章
Vue封裝組件利器之$attrs、$listeners的使用
vue通信手段有很多種,props/emit、vuex、event bus、provide/inject等,還有一種通信方式,那就是$attrs和$listeners,下面這篇文章主要給大家介紹了關(guān)于Vue封裝組件利器之$attrs、$listeners使用的相關(guān)資料,需要的朋友可以參考下2021-12-12element plus中el-upload實(shí)現(xiàn)上傳多張圖片的示例代碼
最近寫(xiě)項(xiàng)目的時(shí)候需要一次上傳多張圖片,本文主要介紹了element plus中el-upload實(shí)現(xiàn)上傳多張圖片的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01Vue Echarts實(shí)現(xiàn)圖表的動(dòng)態(tài)適配以及如何優(yōu)化
這篇文章主要介紹了Vue Echarts實(shí)現(xiàn)圖表的動(dòng)態(tài)適配以及如何優(yōu)化,在實(shí)際的前端開(kāi)發(fā)過(guò)程中,動(dòng)態(tài)適配是一個(gè)非常重要的問(wèn)題,在數(shù)據(jù)可視化的場(chǎng)景下,圖表的動(dòng)態(tài)適配尤為重要,需要的朋友可以參考下2023-05-05Vue3 + Vue-PDF 實(shí)現(xiàn)PDF 文件在線(xiàn)預(yù)覽實(shí)戰(zhàn)
這篇文章主要介紹了Vue3 + Vue-PDF 實(shí)現(xiàn)PDF 文件在線(xiàn)預(yù)覽實(shí)戰(zhàn),文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-06-06iview form清除校驗(yàn)狀態(tài)的實(shí)現(xiàn)
這篇文章主要介紹了iview form清除校驗(yàn)狀態(tài)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09Vue觸發(fā)隱藏input file的方法實(shí)例詳解
這篇文章主要介紹了Vue觸發(fā)隱藏input file的方法實(shí)例詳解,非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-08-08Vue3項(xiàng)目pc端瀏覽器樣式正常但移動(dòng)端部分樣式失效問(wèn)題的解決方法
這篇文章主要介紹了Vue3項(xiàng)目pc端瀏覽器樣式正常但移動(dòng)端部分樣式失效問(wèn)題的解決方法,文中通過(guò)圖文講解的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下2024-07-07