Skip to content

Commit 111bcb1

Browse files
committed
Revert inplace update in v-repeat
Inplace update is causing unwanted behavior in multiple existing use cases, and the perf gain is not substantial enough since the cases where it works properly are quite few.
1 parent efedd6e commit 111bcb1

File tree

2 files changed

+2
-147
lines changed

2 files changed

+2
-147
lines changed

src/directives/repeat.js

Lines changed: 2 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
var _ = require('../util')
2-
var config = require('../config')
32
var isObject = _.isObject
43
var isPlainObject = _.isPlainObject
54
var textParser = require('../parsers/text')
@@ -39,9 +38,6 @@ module.exports = {
3938
this.template = this.el.tagName === 'TEMPLATE'
4039
? templateParser.parse(this.el, true)
4140
: this.el
42-
// check if we need to use diff instead of inplace
43-
// updates
44-
this.checkUpdateStrategy()
4541
// check other directives that need to be handled
4642
// at v-repeat level
4743
this.checkIf()
@@ -54,38 +50,6 @@ module.exports = {
5450
this.cache = Object.create(null)
5551
},
5652

57-
/**
58-
* Check what strategy to use for updates.
59-
*
60-
* If the repeat is simple enough we can use in-place
61-
* updates which simply overwrites existing instances'
62-
* data. This strategy reuses DOM nodes and instances
63-
* as much as possible.
64-
*
65-
* There are two situations where we have to use the
66-
* more complex but more accurate diff algorithm:
67-
* 1. We are using components with or inside v-repeat.
68-
* The components could have private state that needs
69-
* to be preserved across updates.
70-
* 2. We have transitions on the list, which requires
71-
* precise DOM re-positioning.
72-
*/
73-
74-
checkUpdateStrategy: function () {
75-
var components = Object.keys(this.vm.$options.components)
76-
var matcher
77-
if (components.length) {
78-
matcher = new RegExp(
79-
components.map(function (name) {
80-
return '<' + name + '(>|\\s)'
81-
}).join('|') + '|' + config.prefix + 'component'
82-
)
83-
}
84-
this.needDiff =
85-
(matcher && matcher.test(this.template.outerHTML)) ||
86-
this.el.hasAttribute(config.prefix + 'transition')
87-
},
88-
8953
/**
9054
* Warn against v-if usage.
9155
*/
@@ -181,9 +145,7 @@ module.exports = {
181145
} else if (type === 'string') {
182146
data = _.toArray(data)
183147
}
184-
this.vms = this.needDiff
185-
? this.diff(data, this.vms)
186-
: this.inplaceUpdate(data, this.vms)
148+
this.vms = this.diff(data, this.vms)
187149
// update v-ref
188150
if (this.refID) {
189151
this.vm.$[this.refID] = this.vms
@@ -195,43 +157,6 @@ module.exports = {
195157
}
196158
},
197159

198-
/**
199-
* Inplace update that maximally reuses existing vm
200-
* instances and DOM nodes by simply swapping data into
201-
* existing vms.
202-
*
203-
* @param {Array} data
204-
* @param {Array} oldVms
205-
* @return {Array}
206-
*/
207-
208-
inplaceUpdate: function (data, oldVms) {
209-
oldVms = oldVms || []
210-
var vms
211-
var dir = this
212-
var alias = dir.arg
213-
var converted = dir.converted
214-
if (data.length < oldVms.length) {
215-
oldVms.slice(data.length).forEach(function (vm) {
216-
vm.$destroy(true)
217-
})
218-
vms = oldVms.slice(0, data.length)
219-
overwrite(data, vms, alias, converted)
220-
} else if (data.length > oldVms.length) {
221-
var newVms = data.slice(oldVms.length).map(function (data, i) {
222-
var vm = dir.build(data, i + oldVms.length)
223-
vm.$before(dir.ref)
224-
return vm
225-
})
226-
overwrite(data.slice(0, oldVms.length), oldVms, alias, converted)
227-
vms = oldVms.concat(newVms)
228-
} else {
229-
overwrite(data, oldVms, alias, converted)
230-
vms = oldVms
231-
}
232-
return vms
233-
},
234-
235160
/**
236161
* Diff, based on new data and old data, determine the
237162
* minimum amount of DOM manipulations needed to make the
@@ -440,9 +365,7 @@ module.exports = {
440365
var vm
441366
while (i--) {
442367
vm = this.vms[i]
443-
if (this.needDiff) {
444-
this.uncacheVm(vm)
445-
}
368+
this.uncacheVm(vm)
446369
vm.$destroy()
447370
}
448371
}
@@ -613,33 +536,4 @@ function range (n) {
613536
ret[i] = i
614537
}
615538
return ret
616-
}
617-
618-
/**
619-
* Helper function to overwrite new data Array on to
620-
* existing vms. Used in `inplaceUpdate`.
621-
*
622-
* @param {Array} arr
623-
* @param {Array} vms
624-
* @param {String|undefined} alias
625-
* @param {Boolean} converted
626-
*/
627-
628-
function overwrite (arr, vms, alias, converted) {
629-
var vm, data, raw
630-
for (var i = 0, l = arr.length; i < l; i++) {
631-
vm = vms[i]
632-
data = raw = arr[i]
633-
if (converted) {
634-
vm.$key = data.$key
635-
raw = data.$value
636-
}
637-
if (alias) {
638-
vm[alias] = raw
639-
} else if (!isObject(raw)) {
640-
vm.$value = raw
641-
} else {
642-
vm._setData(raw)
643-
}
644-
}
645539
}

test/unit/specs/directives/repeat_spec.js

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -718,45 +718,6 @@ if (_.inBrowser) {
718718
}
719719
})
720720

721-
it('should use diff when block contains component', function (done) {
722-
var spy = jasmine.createSpy()
723-
var obj = { a: 1, b: 2 }
724-
var vm = new Vue({
725-
el: el,
726-
template:
727-
'<div v-repeat="list">' +
728-
'<test-foo v-with="foo: parentFoo"></test-foo>' +
729-
'<div v-component="test-foo" v-with="foo: parentFoo"></div>' +
730-
'</div>',
731-
data: {
732-
list: [1,2]
733-
},
734-
compiled: function () {
735-
this.$set('parentFoo', obj)
736-
},
737-
components: {
738-
'test-foo': {
739-
template: '{{foo.a}}',
740-
watch: {
741-
foo: spy
742-
}
743-
}
744-
}
745-
})
746-
747-
_.nextTick(function () {
748-
expect(spy).toHaveBeenCalledWith(obj, undefined)
749-
expect(spy.calls.count()).toBe(4)
750-
expect(el.innerHTML).toBe([1,2].map(function () {
751-
return '<div>' +
752-
'<test-foo>1</test-foo><!--v-component-->' +
753-
'<div>1</div><!--v-component-->' +
754-
'</div>'
755-
}).join('') + '<!--v-repeat-->')
756-
done()
757-
})
758-
})
759-
760721
})
761722
}
762723

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy