Skip to content

Commit cc7377d

Browse files
committed
default event propagation to false
1 parent 42dc999 commit cc7377d

File tree

4 files changed

+57
-19
lines changed

4 files changed

+57
-19
lines changed

src/api/events.js

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -87,23 +87,20 @@ exports.$off = function (event, fn) {
8787
*/
8888

8989
exports.$emit = function (event) {
90-
this._eventCancelled = false
90+
this._shouldPropagate = false
9191
var cbs = this._events[event]
9292
if (cbs) {
93-
// avoid leaking arguments:
94-
// http://jsperf.com/closure-with-arguments
95-
var i = arguments.length - 1
96-
var args = new Array(i)
97-
while (i--) {
98-
args[i] = arguments[i + 1]
99-
}
100-
i = 0
10193
cbs = cbs.length > 1
10294
? _.toArray(cbs)
10395
: cbs
104-
for (var l = cbs.length; i < l; i++) {
105-
if (cbs[i].apply(this, args) === false) {
106-
this._eventCancelled = true
96+
var args = _.toArray(arguments, 1)
97+
for (var i = 0, l = cbs.length; i < l; i++) {
98+
var res = cbs[i].apply(this, args)
99+
if (res === true) {
100+
this._shouldPropagate = true
101+
}
102+
if (process.env.NODE_ENV !== 'production' && res === false) {
103+
_.deprecation.PROPAGATION(event)
107104
}
108105
}
109106
}
@@ -125,7 +122,7 @@ exports.$broadcast = function (event) {
125122
for (var i = 0, l = children.length; i < l; i++) {
126123
var child = children[i]
127124
child.$emit.apply(child, arguments)
128-
if (!child._eventCancelled) {
125+
if (child._shouldPropagate) {
129126
child.$broadcast.apply(child, arguments)
130127
}
131128
}
@@ -143,9 +140,9 @@ exports.$dispatch = function () {
143140
var parent = this.$parent
144141
while (parent) {
145142
parent.$emit.apply(parent, arguments)
146-
parent = parent._eventCancelled
147-
? null
148-
: parent.$parent
143+
parent = parent._shouldPropagate
144+
? parent.$parent
145+
: null
149146
}
150147
return this
151148
}

src/deprecations.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,15 @@ if (process.env.NODE_ENV !== 'production') {
177177
'The "key" filter will be deprecated in 1.0.0. Use the new ' +
178178
'on-keyup:key="handler" syntax instead.'
179179
)
180+
},
181+
182+
PROPAGATION: function (event) {
183+
warn(
184+
'No need to return false in handler for event "' + event + '": events ' +
185+
'no longer propagate beyond the first triggered handler unless the ' +
186+
'handler explicitly returns true. See https://github.com/yyx990803/vue/issues/1175 ' +
187+
'for more details.'
188+
)
180189
}
181190

182191
}

src/instance/init.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ exports._init = function (options) {
3131
// events bookkeeping
3232
this._events = {} // registered callbacks
3333
this._eventsCount = {} // for $broadcast optimization
34-
this._eventCancelled = false // for event cancellation
34+
this._shouldPropagate = false // for event propagation
3535

3636
// fragment instance properties
3737
this._isFragment = false

test/unit/specs/api/events_spec.js

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,20 @@ describe('Events API', function () {
6666
child2.$on('test', spy)
6767
child3.$on('test', spy)
6868
vm.$broadcast('test')
69+
expect(spy.calls.count()).toBe(2) // should not propagate by default
70+
})
71+
72+
it('$broadcast with propagation', function () {
73+
var child1 = vm.$addChild()
74+
var child2 = vm.$addChild()
75+
var child3 = child1.$addChild()
76+
child1.$on('test', function () {
77+
spy()
78+
return true
79+
})
80+
child2.$on('test', spy)
81+
child3.$on('test', spy)
82+
vm.$broadcast('test')
6983
expect(spy.calls.count()).toBe(3)
7084
})
7185

@@ -75,7 +89,13 @@ describe('Events API', function () {
7589
// hooks should not incurr the bookkeeping cost
7690
child.$on('hook:created', function () {})
7791
expect(vm._eventsCount['hook:created']).toBeUndefined()
78-
child.$on('test', spy)
92+
93+
function handler () {
94+
spy()
95+
return true
96+
}
97+
98+
child.$on('test', handler)
7999
expect(vm._eventsCount['test']).toBe(1)
80100
// child2's $emit & $broadcast
81101
// shouldn't get called if no child listens to the event
@@ -84,7 +104,7 @@ describe('Events API', function () {
84104
vm.$broadcast('test')
85105
expect(spy.calls.count()).toBe(1)
86106
// check $off bookkeeping
87-
child.$off('test', spy)
107+
child.$off('test', handler)
88108
expect(vm._eventsCount['test']).toBe(0)
89109
function noop () {}
90110
child.$on('test', noop)
@@ -117,6 +137,18 @@ describe('Events API', function () {
117137
child.$on('test', spy)
118138
vm.$on('test', spy)
119139
child2.$dispatch('test')
140+
expect(spy.calls.count()).toBe(1) // should not propagate by default
141+
})
142+
143+
it('$dispatch with propagation', function () {
144+
var child = vm.$addChild()
145+
var child2 = child.$addChild()
146+
child.$on('test', function () {
147+
spy()
148+
return true
149+
})
150+
vm.$on('test', spy)
151+
child2.$dispatch('test')
120152
expect(spy.calls.count()).toBe(2)
121153
})
122154

0 commit comments

Comments
 (0)