Let’s start with a bug
In one requirement, I needed to implement a drag function, which I used sortable.js to implement, but I found that the data I dragged was not rendered on the page.
In short, for example, the original array was [1,2,3,4]. After dragging, it became [4,1,2,3], but it didn’t show up in the view. This left me confused and started exploring the following questions, which I noted here
Vue array update problem
Given the above, you might think I’m not handling the array the right way, since the official documentation clearly points out several holes in the array
Due to JavaScript limitations, Vue cannot detect changes to the following arrays: 1. When you set an array item directly using an index, for example, vm.items[indexOfItem] = newValue 2. When you modify the length of an array, for example, vm.items. Length = newLength
But actually, I avoided this pit, and the actual implementation was done by Splice, so that there was actually no problem.
const tempItem = me.tabs.splice(e.oldIndex, 1)[0]
me.tabs.splice(e.newIndex, 0, tempItem)
Copy the code
As an aside, we actually use splice, push and other methods in Vue’s array books. Vue has wrapped them so that they can update views. If you want to know more, you can read the source code.
Vue force refresh — $forceUpdate()
As for this, Yudhoyono says that in general, what we don’t need to use, 99.9 percent of the time if we do, is our own problem.
The $forceUpdate() function forces the instance to re-render, but it has no effect. I think I used it wrong.
A similar code would look like this:
// Force render updates when control variables changelet childrenRefs = this.$refs.elTabs.$children
this.$nextTick(() => {
childrenRefs.forEach(child => child.$forceUpdate()})Copy the code
Reference: www.imooc.com/wenda/detai…
The final solution
In fact, I have some doubts about the final solution, which comes from the SegmentFault, so without further ado, let’s look at the code
The data is first deep-copied using a slice method, then null, and then the deep-copied array values are assigned in $nextTick. Finally it’s ok.
My guess is that there are two, the length of the array is the same, but the length of the array is changed, and Vue cannot detect it. For this guess, it is easy to be overturned by myself, after all, try it, it will not be like this.
That might be a problem with sortable.js
/ / code reference: https://segmentfault.com/q/1010000009672767
mounted : function () {
var that = this;
var sortable1 = new Sortable(document.querySelector('#topicNumBox'), {
sort: true.animation: 300.onEnd: function (evt) { // The event occurs when the drag ends
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; }); }}); }Copy the code
conclusion
Although the problem was solved, the ultimate root cause was not found…
But there are one or two powerful ways to refresh data that you can try later (hopefully you won’t)
Welcome everyone to pay attention to my public number ~ front big grocery store ~