sortable.js——Vue 數據更新問題

從一個 bug 提及

在一個需求中,我須要實現一個拖拽的功能,其中我使用了 sortable.js 去實現,但我發現我拖拽以後的數據並無渲染在頁面上。html

簡而言之,舉個例子,原先的數組是 [1,2,3,4],拖拽以後,變成了 [4,1,2,3],但在視圖上並無顯現,這不經讓我迷惑不解,開始瞭如下問題的探索,在此記錄一下前端

Vue 的數組更新問題

看到以上問題,你確定會認爲我處理數組的方式不對,畢竟官方文檔明確指出了數組的幾個坑vue

如下參考 Vue 文檔 因爲 JavaScript 的限制,Vue 不能檢測如下數組的變更: 1.當你利用索引直接設置一個數組項時,例如:vm.items[indexOfItem] = newValue 2.當你修改數組的長度時,例如:vm.items.length = newLengthreact

可是實際上,我避開了這個坑,實際的實現是經過 splice 實現的,這樣其實是不會有問題的。git

const tempItem = me.tabs.splice(e.oldIndex, 1)[0]
me.tabs.splice(e.newIndex, 0, tempItem)
複製代碼

題外話 實際上,咱們在 Vue 的數組書使用 splicepush等方法,Vue 都已經作了一層封裝,因此它們才能出發視圖更新,若是有想更加深刻了解,能夠閱讀源碼github

Vue 強制刷新——$forceUpdate()

對於這一點,尤大大表示,通常而言,咱們都不須要用到的,若是須要用到的話,99.9%的狀況,是自身的問題。segmentfault

$forceUpdate() 的功能,就是迫使實例從新渲染,但尷尬的是,我使用了以後並無效果,我以爲是我用錯了,O__O "…數組

相似的代碼以下:bash

// 在控制變量改變的時候進行 強制渲染更新

let childrenRefs = this.$refs.elTabs.$children
this.$nextTick(() => {
  childrenRefs.forEach(child => child.$forceUpdate())
})
複製代碼

參考:www.imooc.com/wenda/detai…ui

最後的解決方法

其實對於最後的解決方法,來源於 segmentfault,我仍是心存疑問的,廢話少說,咱們來看代碼

先用一個數據深拷貝數據,這裏使用了 slice 方法,而後置空,最後在 $nextTick 中賦值深拷貝出來的數組值。最後能夠了。

我猜想有兩個,數組的長度不變,只是數組的長度變化, Vue檢測不到,對於這個猜測,很容易就被本身推翻了,畢竟試了一下,並不會這樣的。

那就多是 sortable.js 的問題了

// 代碼參考:https://segmentfault.com/q/1010000009672767
mounted : function () {
  var that = this;
  var sortable1 = new Sortable(document.querySelector('#topicNumBox'), {
    sort: true,
    animation: 300,
    onEnd: function (evt) {  //拖拽結束髮生該事件
      that.questionData.splice(evt.newIndex, 0, that.questionData.splice(evt.oldIndex, 1)[0]);
      var newArray = that.questionData.slice(0);
      that.questionData = [];
      that.$nextTick(function () {
        that.questionData = newArray;
      });
    },
  });
}
複製代碼

結論

雖然問題解決了,可是最終的根源並無找到O__O "…

但也提供一兩種很強勢的刷新數據的方法,之後須要用到的時候能夠試下(願你不會用到)

歡迎你們關注個人公衆號~前端大雜貨鋪~

相關文章
相關標籤/搜索