Skip to content

Commit 767e623

Browse files
committed
add back support for non-standard literal keys in track-by
1 parent 47375c5 commit 767e623

File tree

2 files changed

+66
-15
lines changed

2 files changed

+66
-15
lines changed

src/directives/public/for.js

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -403,11 +403,7 @@ const vFor = {
403403
var primitive = !isObject(value)
404404
var id
405405
if (key || trackByKey || primitive) {
406-
id = trackByKey
407-
? trackByKey === '$index'
408-
? index
409-
: getPath(value, trackByKey)
410-
: (key || value)
406+
id = getTrackByKey(index, key, value, trackByKey)
411407
if (!cache[id]) {
412408
cache[id] = frag
413409
} else if (trackByKey !== '$index') {
@@ -444,11 +440,7 @@ const vFor = {
444440
var primitive = !isObject(value)
445441
var frag
446442
if (key || trackByKey || primitive) {
447-
var id = trackByKey
448-
? trackByKey === '$index'
449-
? index
450-
: getPath(value, trackByKey)
451-
: (key || value)
443+
var id = getTrackByKey(index, key, value, trackByKey)
452444
frag = this.cache[id]
453445
} else {
454446
frag = value[this.id]
@@ -476,11 +468,7 @@ const vFor = {
476468
var key = hasOwn(scope, '$key') && scope.$key
477469
var primitive = !isObject(value)
478470
if (trackByKey || key || primitive) {
479-
var id = trackByKey
480-
? trackByKey === '$index'
481-
? index
482-
: getPath(value, trackByKey)
483-
: (key || value)
471+
var id = getTrackByKey(index, key, value, trackByKey)
484472
this.cache[id] = null
485473
} else {
486474
value[this.id] = null
@@ -635,6 +623,25 @@ function range (n) {
635623
return ret
636624
}
637625

626+
/**
627+
* Get the track by key for an item.
628+
*
629+
* @param {Number} index
630+
* @param {String} key
631+
* @param {*} value
632+
* @param {String} [trackByKey]
633+
*/
634+
635+
function getTrackByKey (index, key, value, trackByKey) {
636+
return trackByKey
637+
? trackByKey === '$index'
638+
? index
639+
: trackByKey.charAt(0).match(/\w/)
640+
? getPath(value, trackByKey)
641+
: value[trackByKey]
642+
: (key || value)
643+
}
644+
638645
if (process.env.NODE_ENV !== 'production') {
639646
vFor.warnDuplicate = function (value) {
640647
warn(

test/unit/specs/directives/public/for/for_spec.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,50 @@ describe('v-for', function () {
572572
}
573573
})
574574

575+
it('track by non-standard id path', function (done) {
576+
var vm = new Vue({
577+
el: el,
578+
template: '<test v-for="item in list" :item="item" track-by=".id"></test>',
579+
data: {
580+
list: [
581+
{ '.id': 1, msg: 'foo' },
582+
{ '.id': 2, msg: 'bar' },
583+
{ '.id': 3, msg: 'baz' }
584+
]
585+
},
586+
components: {
587+
test: {
588+
props: ['item'],
589+
template: '{{item.msg}}'
590+
}
591+
}
592+
})
593+
assertMarkup()
594+
var oldVms = vm.$children.slice()
595+
// swap the data with different objects, but with
596+
// the same ID!
597+
vm.list = [
598+
{ '.id': 1, msg: 'qux' },
599+
{ '.id': 2, msg: 'quux' }
600+
]
601+
_.nextTick(function () {
602+
assertMarkup()
603+
// should reuse old vms!
604+
var i = 2
605+
while (i--) {
606+
expect(vm.$children[i]).toBe(oldVms[i])
607+
}
608+
done()
609+
})
610+
611+
function assertMarkup () {
612+
var markup = vm.list.map(function (item) {
613+
return '<test>' + item.msg + '</test>'
614+
}).join('')
615+
expect(el.innerHTML).toBe(markup)
616+
}
617+
})
618+
575619
it('track by $index', function (done) {
576620
var vm = new Vue({
577621
el: el,

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