Skip to content

Commit ea9c6c3

Browse files
committed
support v-on .native modifier on components
1 parent 7a5028c commit ea9c6c3

File tree

7 files changed

+32
-7
lines changed

7 files changed

+32
-7
lines changed

flow/compiler.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ declare type ASTElement = {
102102
styleBinding?: string,
103103
hooks?: ASTElementHooks,
104104
events?: ASTElementHandlers,
105+
nativeEvents?: ASTElementHandlers,
105106

106107
transition?: string | true,
107108
transitionOnAppear?: boolean,

flow/vnode.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ declare interface VNodeData {
4444
domProps?: { [key: string]: any };
4545
staticAttrs?: { [key: string]: string };
4646
hook?: { [key: string]: Function };
47-
on?: { [key: string]: Function | Array<Function> };
47+
on?: ?{ [key: string]: Function | Array<Function> };
48+
nativeOn?: { [key: string]: Function | Array<Function> };
4849
transition?: Object;
4950
inlineTemplate?: {
5051
render: Function,

src/compiler/codegen/events.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ const modifierCode = {
2121
self: 'if($event.target !== $event.currentTarget)return;'
2222
}
2323

24-
export function genHandlers (events: ASTElementHandlers): string {
25-
let res = 'on:{'
24+
export function genHandlers (events: ASTElementHandlers, native?: boolean): string {
25+
let res = native ? 'nativeOn:{' : 'on:{'
2626
for (const name in events) {
2727
res += `"${name}":${genHandler(events[name])},`
2828
}

src/compiler/codegen/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,9 @@ function genData (el: ASTElement): string | void {
166166
if (el.events) {
167167
data += `${genHandlers(el.events)},`
168168
}
169+
if (el.nativeEvents) {
170+
data += `${genHandlers(el.nativeEvents, true)}`
171+
}
169172
// inline-template
170173
if (el.inlineTemplate) {
171174
const ast = el.children[0]

src/compiler/helpers.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,18 @@ export function addHandler (
5252
value: string,
5353
modifiers: ?{ [key: string]: true }
5454
) {
55-
const events = el.events || (el.events = {})
5655
// check capture modifier
5756
if (modifiers && modifiers.capture) {
5857
delete modifiers.capture
5958
name = '!' + name // mark the event as captured
6059
}
60+
let events
61+
if (modifiers && modifiers.native) {
62+
delete modifiers.native
63+
events = el.nativeEvents || (el.nativeEvents = {})
64+
} else {
65+
events = el.events || (el.events = {})
66+
}
6167
const newHandler = { value, modifiers }
6268
const handlers = events[name]
6369
/* istanbul ignore if */

src/core/vdom/create-component.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,8 @@ export function createComponent (
8989
// extract listeners, since these needs to be treated as
9090
// child component listeners instead of DOM listeners
9191
const listeners = data.on
92-
if (listeners) {
93-
delete data.on
94-
}
92+
// replace with listeners with .native modifier
93+
data.on = data.nativeOn
9594

9695
// return a placeholder vnode
9796
const name = Ctor.options.name || tag

test/unit/features/directives/on.spec.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,21 @@ describe('Directive v-on', () => {
152152
expect(spy).toHaveBeenCalledWith('foo', 'bar')
153153
})
154154

155+
it('should be able to bind native events for a child component', () => {
156+
Vue.component('bar', {
157+
template: '<span>Hello</span>'
158+
})
159+
vm = new Vue({
160+
el,
161+
template: '<bar @click.native="foo"></bar>',
162+
methods: { foo: spy }
163+
})
164+
vm.$children[0].$emit('click')
165+
expect(spy).not.toHaveBeenCalled()
166+
triggerEvent(vm.$children[0].$el, 'click')
167+
expect(spy).toHaveBeenCalled()
168+
})
169+
155170
it('remove listener', done => {
156171
const spy2 = jasmine.createSpy('remove listener')
157172
vm = new Vue({

0 commit comments

Comments
 (0)