Skip to content

Commit bcd3737

Browse files
committed
warn special case for v-repeat $value sync
1 parent 12dfd60 commit bcd3737

File tree

3 files changed

+32
-4
lines changed

3 files changed

+32
-4
lines changed

src/directives/repeat.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,16 @@ module.exports = {
384384
(type === 'string' || type === 'number')
385385
) {
386386
vm.$watch(alias || '$value', function (val) {
387+
if (dir.filters) {
388+
_.warn(
389+
'You seem to be mutating the $value reference of ' +
390+
'a v-repeat instance (likely through v-model) ' +
391+
'and filtering the v-repeat at the same time. ' +
392+
'This will not work properly with an Array of ' +
393+
'primitive values. Please use an Array of ' +
394+
'Objects instead.'
395+
)
396+
}
387397
dir._withLock(function () {
388398
if (dir.converted) {
389399
dir.rawValue[vm.$key] = val

src/util/debug.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ function enableDebug () {
3636
/* istanbul ignore if */
3737
if (config.debug) {
3838
/* jshint debug: true */
39-
console.warn((e || new Error()).stack)
39+
console.warn((e || new Error('Warning Stack Trace')).stack)
4040
}
4141
}
4242
}

test/unit/specs/directives/repeat_spec.js

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -623,27 +623,45 @@ if (_.inBrowser) {
623623
}, 100)
624624
})
625625

626-
it('sync $value changes back to original array/object', function (done) {
626+
it('sync $value/alias changes back to original array/object', function (done) {
627627
var vm = new Vue({
628628
el: el,
629629
template:
630630
'<div v-repeat="items">{{$value}}</div>' +
631-
'<div v-repeat="obj">{{$value}}</div>',
631+
'<div v-repeat="obj">{{$value}}</div>' +
632+
'<div v-repeat="val:vals">{{val}}</div>',
632633
data: {
633634
items: ['a', 'b'],
634-
obj: { foo: 'a', bar: 'b' }
635+
obj: { foo: 'a', bar: 'b' },
636+
vals: [1, 2]
635637
}
636638
})
637639
vm._children[0].$value = 'c'
638640
var key = vm._children[2].$key
639641
vm._children[2].$value = 'd'
642+
vm._children[4].val = 3
640643
_.nextTick(function () {
641644
expect(vm.items[0]).toBe('c')
642645
expect(vm.obj[key]).toBe('d')
646+
expect(vm.vals[0]).toBe(3)
643647
done()
644648
})
645649
})
646650

651+
it('warn $value sync with filters', function () {
652+
var vm = new Vue({
653+
el: el,
654+
template: '<div v-repeat="items | orderBy \'$value\'"></div>',
655+
data: {
656+
items: ['a', 'b']
657+
}
658+
})
659+
vm._children[0].$value = 'c'
660+
_.nextTick(function () {
661+
expect(hasWarned(_, 'use an Array of Objects instead')).toBe(true)
662+
})
663+
})
664+
647665
it('nested track by', function (done) {
648666
assertTrackBy('<div v-repeat="list" track-by="id">{{msg}}<div v-repeat="list" track-by="id">{{msg}}</div></div>', function () {
649667
assertTrackBy('<div v-repeat="list" track-by="id">{{msg}}<div v-repeat="list" track-by="id">{{msg}}</div></div>', done)

0 commit comments

Comments
 (0)