Skip to content

Commit 4987eeb

Browse files
committed
feat: v-on automatic key inference
1 parent 9761072 commit 4987eeb

File tree

5 files changed

+41
-16
lines changed

5 files changed

+41
-16
lines changed

flow/component.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ declare interface Component {
126126
// apply v-on object
127127
_g: (data: any, value: any) => VNodeData;
128128
// check custom keyCode
129-
_k: (eventKeyCode: number, key: string, builtInAlias: number | Array<number> | void) => boolean;
129+
_k: (eventKeyCode: number, key: string, builtInAlias?: number | Array<number>, eventKeyName?: string) => ?boolean;
130130
// resolve scoped slots
131131
_u: (scopedSlots: ScopedSlotsData, res?: Object) => { [key: string]: Function };
132132

src/compiler/codegen/events.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,11 @@ function genFilterCode (key: string): string {
124124
if (keyVal) {
125125
return `$event.keyCode!==${keyVal}`
126126
}
127-
const alias = keyCodes[key]
128-
return `_k($event.keyCode,${JSON.stringify(key)}${alias ? ',' + JSON.stringify(alias) : ''})`
127+
const code = keyCodes[key]
128+
return (
129+
`_k($event.keyCode,` +
130+
`${JSON.stringify(key)},` +
131+
`${JSON.stringify(code)},` +
132+
`$event.key)`
133+
)
129134
}
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
11
/* @flow */
22

33
import config from 'core/config'
4+
import { hyphenate } from 'shared/util'
45

56
/**
67
* Runtime helper for checking keyCodes from config.
8+
* exposed as Vue.prototype._k
9+
* passing in eventKeyName as last argument separately for backwards compat
710
*/
811
export function checkKeyCodes (
912
eventKeyCode: number,
1013
key: string,
11-
builtInAlias: number | Array<number> | void
12-
): boolean {
14+
builtInAlias?: number | Array<number>,
15+
eventKeyName?: string
16+
): ?boolean {
1317
const keyCodes = config.keyCodes[key] || builtInAlias
14-
if (Array.isArray(keyCodes)) {
15-
return keyCodes.indexOf(eventKeyCode) === -1
16-
} else {
17-
return keyCodes !== eventKeyCode
18+
if (keyCodes) {
19+
if (Array.isArray(keyCodes)) {
20+
return keyCodes.indexOf(eventKeyCode) === -1
21+
} else {
22+
return keyCodes !== eventKeyCode
23+
}
24+
} else if (eventKeyName) {
25+
return hyphenate(eventKeyName) !== key
1826
}
1927
}

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

+12
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,18 @@ describe('Directive v-on', () => {
205205
expect(spy).toHaveBeenCalled()
206206
})
207207

208+
it('should support automatic key name inference', () => {
209+
vm = new Vue({
210+
el,
211+
template: `<input @keyup.arrow-right="foo">`,
212+
methods: { foo: spy }
213+
})
214+
triggerEvent(vm.$el, 'keyup', e => {
215+
e.key = 'ArrowRight'
216+
})
217+
expect(spy).toHaveBeenCalled()
218+
})
219+
208220
// ctrl, shift, alt, meta
209221
it('should support system modifers', () => {
210222
vm = new Vue({

test/unit/modules/compiler/codegen.spec.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -243,17 +243,17 @@ describe('codegen', () => {
243243
it('generate events with keycode', () => {
244244
assertCodegen(
245245
'<input @input.enter="onInput">',
246-
`with(this){return _c('input',{on:{"input":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13))return null;onInput($event)}}})}`
246+
`with(this){return _c('input',{on:{"input":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13,$event.key))return null;onInput($event)}}})}`
247247
)
248248
// multiple keycodes (delete)
249249
assertCodegen(
250250
'<input @input.delete="onInput">',
251-
`with(this){return _c('input',{on:{"input":function($event){if(!('button' in $event)&&_k($event.keyCode,"delete",[8,46]))return null;onInput($event)}}})}`
251+
`with(this){return _c('input',{on:{"input":function($event){if(!('button' in $event)&&_k($event.keyCode,"delete",[8,46],$event.key))return null;onInput($event)}}})}`
252252
)
253253
// multiple keycodes (chained)
254254
assertCodegen(
255255
'<input @keydown.enter.delete="onInput">',
256-
`with(this){return _c('input',{on:{"keydown":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13)&&_k($event.keyCode,"delete",[8,46]))return null;onInput($event)}}})}`
256+
`with(this){return _c('input',{on:{"keydown":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13,$event.key)&&_k($event.keyCode,"delete",[8,46],$event.key))return null;onInput($event)}}})}`
257257
)
258258
// number keycode
259259
assertCodegen(
@@ -263,7 +263,7 @@ describe('codegen', () => {
263263
// custom keycode
264264
assertCodegen(
265265
'<input @input.custom="onInput">',
266-
`with(this){return _c('input',{on:{"input":function($event){if(!('button' in $event)&&_k($event.keyCode,"custom"))return null;onInput($event)}}})}`
266+
`with(this){return _c('input',{on:{"input":function($event){if(!('button' in $event)&&_k($event.keyCode,"custom",undefined,$event.key))return null;onInput($event)}}})}`
267267
)
268268
})
269269

@@ -286,12 +286,12 @@ describe('codegen', () => {
286286
it('generate events with generic modifiers and keycode correct order', () => {
287287
assertCodegen(
288288
'<input @keydown.enter.prevent="onInput">',
289-
`with(this){return _c('input',{on:{"keydown":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13))return null;$event.preventDefault();onInput($event)}}})}`
289+
`with(this){return _c('input',{on:{"keydown":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13,$event.key))return null;$event.preventDefault();onInput($event)}}})}`
290290
)
291291

292292
assertCodegen(
293293
'<input @keydown.enter.stop="onInput">',
294-
`with(this){return _c('input',{on:{"keydown":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13))return null;$event.stopPropagation();onInput($event)}}})}`
294+
`with(this){return _c('input',{on:{"keydown":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13,$event.key))return null;$event.stopPropagation();onInput($event)}}})}`
295295
)
296296
})
297297

@@ -398,7 +398,7 @@ describe('codegen', () => {
398398
// with modifiers
399399
assertCodegen(
400400
`<input @keyup.enter="e=>current++">`,
401-
`with(this){return _c('input',{on:{"keyup":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13))return null;(e=>current++)($event)}}})}`
401+
`with(this){return _c('input',{on:{"keyup":function($event){if(!('button' in $event)&&_k($event.keyCode,"enter",13,$event.key))return null;(e=>current++)($event)}}})}`
402402
)
403403
})
404404

0 commit comments

Comments
 (0)