在一個需求中,我須要實現一個拖拽的功能,其中我使用了 sortable.js
去實現,但我發現我拖拽以後的數據並無渲染在頁面上。html
簡而言之,舉個例子,原先的數組是 [1,2,3,4],拖拽以後,變成了 [4,1,2,3],但在視圖上並無顯現,這不經讓我迷惑不解,開始瞭如下問題的探索,在此記錄一下前端
看到以上問題,你確定會認爲我處理數組的方式不對,畢竟官方文檔明確指出了數組的幾個坑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
的數組書使用 splice
、push
等方法,Vue
都已經作了一層封裝,因此它們才能出發視圖更新,若是有想更加深刻了解,能夠閱讀源碼。github
對於這一點,尤大大表示,通常而言,咱們都不須要用到的,若是須要用到的話,99.9%的狀況,是自身的問題。segmentfault
而 $forceUpdate()
的功能,就是迫使實例從新渲染,但尷尬的是,我使用了以後並無效果,我以爲是我用錯了,O__O "…數組
相似的代碼以下:bash
// 在控制變量改變的時候進行 強制渲染更新
let childrenRefs = this.$refs.elTabs.$children
this.$nextTick(() => {
childrenRefs.forEach(child => child.$forceUpdate())
})
複製代碼
其實對於最後的解決方法,來源於 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 "…
但也提供一兩種很強勢的刷新數據的方法,之後須要用到的時候能夠試下(願你不會用到)
歡迎你們關注個人公衆號~前端大雜貨鋪~