Skip to content

Commit 493aef0

Browse files
committed
ensure dynamic method resolution for component inline v-on (fix vuejs#2670)
1 parent 767e623 commit 493aef0

File tree

3 files changed

+18
-13
lines changed

3 files changed

+18
-13
lines changed

src/instance/api/data.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { del, toArray } from '../../util/index'
33
import { parseText } from '../../parsers/text'
44
import { parseDirective } from '../../parsers/directive'
55
import { getPath } from '../../parsers/path'
6-
import { isSimplePath, parseExpression } from '../../parsers/expression'
6+
import { parseExpression } from '../../parsers/expression'
77

88
const filterRE = /[^|]\|[^|]/
99

@@ -19,7 +19,7 @@ export default function (Vue) {
1919
Vue.prototype.$get = function (exp, asStatement) {
2020
var res = parseExpression(exp)
2121
if (res) {
22-
if (asStatement && !isSimplePath(exp)) {
22+
if (asStatement) {
2323
var self = this
2424
return function statementHandler () {
2525
self.$arguments = toArray(arguments)

src/instance/internal/events.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { isSimplePath } from '../../parsers/expression'
12
import {
23
inDoc,
34
isArray,
@@ -31,22 +32,21 @@ export default function (Vue) {
3132

3233
function registerComponentEvents (vm, el) {
3334
var attrs = el.attributes
34-
var name, handler
35+
var name, value, handler
3536
for (var i = 0, l = attrs.length; i < l; i++) {
3637
name = attrs[i].name
3738
if (eventRE.test(name)) {
3839
name = name.replace(eventRE, '')
39-
handler = (vm._scope || vm._context).$eval(attrs[i].value, true)
40-
if (typeof handler === 'function') {
41-
handler._fromParent = true
42-
vm.$on(name.replace(eventRE), handler)
43-
} else if (process.env.NODE_ENV !== 'production') {
44-
warn(
45-
'v-on:' + name + '="' + attrs[i].value + '" ' +
46-
'expects a function value, got ' + handler,
47-
vm
48-
)
40+
// force the expression into a statement so that
41+
// it always dynamically resolves the method to call (#2670)
42+
// kinda ugly hack, but does the job.
43+
value = attrs[i].value
44+
if (isSimplePath(value)) {
45+
value += '.apply(this, $arguments)'
4946
}
47+
handler = (vm._scope || vm._context).$eval(value, true)
48+
handler._fromParent = true
49+
vm.$on(name.replace(eventRE), handler)
5050
}
5151
}
5252
}

test/unit/specs/instance/events_spec.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ describe('Instance Events', function () {
206206
})
207207

208208
it('compile v-on on child component', function () {
209+
var spy2 = jasmine.createSpy()
209210
var vm = new Vue({
210211
el: document.createElement('div'),
211212
template: '<comp v-on:hook:created="onCreated" @ready="onReady" @ok="a++"></comp>',
@@ -221,12 +222,16 @@ describe('Instance Events', function () {
221222
compiled: function () {
222223
this.$emit('ready', 123)
223224
this.$emit('ok')
225+
this.$parent.onReady = spy2
226+
this.$emit('ready', 234)
224227
}
225228
}
226229
}
227230
})
228231
expect(spy.calls.count()).toBe(2)
229232
expect(spy).toHaveBeenCalledWith(123)
233+
expect(spy2.calls.count()).toBe(1)
234+
expect(spy2).toHaveBeenCalledWith(234)
230235
expect(vm.a).toBe(1)
231236
})
232237

0 commit comments

Comments
 (0)