Skip to content

Commit aacf90a

Browse files
committed
revert vuejs#3217 and warn v-for + v-if mixed usage (fix vuejs#3754)
1 parent eca73f2 commit aacf90a

File tree

5 files changed

+21
-99
lines changed

5 files changed

+21
-99
lines changed

src/compiler/compile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,7 @@ function makeTerminalNodeLinkFn (el, dirName, value, options, def, rawName, arg,
674674
def: def
675675
}
676676
// check ref for v-for, v-if and router-view
677-
if (dirName === 'for' || dirName === 'if' || dirName === 'router-view') {
677+
if (dirName === 'for' || dirName === 'router-view') {
678678
descriptor.ref = findRef(el)
679679
}
680680
var fn = function terminalNodeLinkFn (vm, el, host, scope, frag) {

src/directives/public/for.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@ const vFor = {
3535
],
3636

3737
bind () {
38+
if (process.env.NODE_ENV !== 'production' && this.el.hasAttribute('v-if')) {
39+
warn(
40+
`<${this.el.tagName.toLowerCase()} v-for="${this.expression}" v-if="${this.el.getAttribute('v-if')}">: ` +
41+
`Using v-if and v-for on the same element is not recommended - ` +
42+
`consider filtering the source Array instead.`,
43+
this.vm
44+
)
45+
}
46+
3847
// support "item in/of items" syntax
3948
var inMatch = this.expression.match(/(.*) (?:in|of) (.*)/)
4049
if (inMatch) {

src/directives/public/if.js

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,8 @@ export default {
4141
if (value) {
4242
if (!this.frag) {
4343
this.insert()
44-
this.updateRef(value)
4544
}
4645
} else {
47-
this.updateRef(value)
4846
this.remove()
4947
}
5048
},
@@ -79,29 +77,6 @@ export default {
7977
}
8078
},
8179

82-
updateRef (value) {
83-
var ref = this.descriptor.ref
84-
if (!ref) return
85-
var hash = (this.vm || this._scope).$refs
86-
var refs = hash[ref]
87-
var key = this._frag.scope.$key
88-
if (!refs) return
89-
if (value) {
90-
if (Array.isArray(refs)) {
91-
refs.push(findVmFromFrag(this._frag))
92-
} else {
93-
refs[key] = findVmFromFrag(this._frag)
94-
}
95-
} else {
96-
if (Array.isArray(refs)) {
97-
refs.$remove(findVmFromFrag(this._frag))
98-
} else {
99-
refs[key] = null
100-
delete refs[key]
101-
}
102-
}
103-
},
104-
10580
unbind () {
10681
if (this.frag) {
10782
this.frag.destroy()

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,17 @@ describe('v-for', function () {
10011001
})
10021002
expect('Frozen v-for objects cannot be automatically tracked').toHaveBeenWarned()
10031003
})
1004+
1005+
it('warn v-if and v-for mixed usage', () => {
1006+
new Vue({
1007+
el: document.createElement('div'),
1008+
template: '<div v-for="item in items" v-if="ok"></div>',
1009+
data: {
1010+
items: []
1011+
}
1012+
})
1013+
expect('consider filtering the source Array instead').toHaveBeenWarned()
1014+
})
10041015
})
10051016

10061017
/**

test/unit/specs/directives/public/if_spec.js

Lines changed: 0 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -432,77 +432,4 @@ describe('v-if', function () {
432432
done()
433433
})
434434
})
435-
436-
// GitHub issue #3204
437-
it('update array refs', function (done) {
438-
var vm = new Vue({
439-
el: el,
440-
template: '<foo v-if="!activeItem || $index === activeItem" v-ref:foo :index="$index" v-for="item in items"></foo>',
441-
data: {
442-
items: [0, 1, 2],
443-
activeItem: null
444-
},
445-
components: {
446-
foo: {
447-
props: ['index'],
448-
template: '<div>I am foo ({{ index }})<div>'
449-
}
450-
}
451-
})
452-
vm.$refs.foo.forEach(function (ref, index) {
453-
expect(ref.$el.textContent).toBe('I am foo (' + index + ')')
454-
expect(ref.index).toBe(index)
455-
})
456-
vm.activeItem = 1 // select active item
457-
nextTick(function () {
458-
expect(vm.$refs.foo.length).toBe(1)
459-
expect(vm.$refs.foo[0].index).toBe(1)
460-
vm.activeItem = null // enable all elements
461-
nextTick(function () {
462-
expect(vm.$refs.foo.length).toBe(3)
463-
done()
464-
})
465-
})
466-
})
467-
468-
it('update object refs', function (done) {
469-
var vm = new Vue({
470-
el: el,
471-
template: '<foo v-if="!activeKey || $key === activeKey" v-ref:foo :key="$key" v-for="item in items"></foo>',
472-
data: {
473-
items: {
474-
a: 1,
475-
b: 2,
476-
c: 3
477-
},
478-
activeKey: null
479-
},
480-
components: {
481-
foo: {
482-
props: ['key'],
483-
template: '<div>I am foo ({{ key }})<div>'
484-
}
485-
}
486-
})
487-
Object.keys(vm.$refs.foo).forEach(function (key) {
488-
var ref = vm.$refs.foo[key]
489-
expect(ref.$el.textContent).toBe('I am foo (' + key + ')')
490-
expect(ref.key).toBe(key)
491-
})
492-
vm.activeKey = 'b' // select active item
493-
nextTick(function () {
494-
expect(Object.keys(vm.$refs.foo).length).toBe(1)
495-
expect(vm.$refs.foo['b'].key).toBe('b')
496-
vm.activeKey = null // enable all elements
497-
nextTick(function () {
498-
expect(Object.keys(vm.$refs.foo).length).toBe(3)
499-
Object.keys(vm.$refs.foo).forEach(function (key) {
500-
var ref = vm.$refs.foo[key]
501-
expect(ref.$el.textContent).toBe('I am foo (' + key + ')')
502-
expect(ref.key).toBe(key)
503-
})
504-
done()
505-
})
506-
})
507-
})
508435
})

0 commit comments

Comments
 (0)