Skip to content

Commit 6ea9a4d

Browse files
defccyyx990803
authored andcommitted
Support mutliple keys for keycode (#4328)
* support mutliple keys for keycode * update flow type * add test case * update comment * update flow type * update comment
1 parent 9215ff0 commit 6ea9a4d

File tree

5 files changed

+49
-23
lines changed

5 files changed

+49
-23
lines changed

flow/component.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@ declare interface Component {
104104
_t: (name: string, fallback: ?Array<VNode>, props: ?Object) => ?Array<VNode>;
105105
// apply v-bind object
106106
_b: (data: any, value: any, asProp?: boolean) => VNodeData;
107-
// retrive custom keyCode
108-
_k: (key: string) => ?number;
107+
// check custom keyCode
108+
_k: (eventKeyCode: number, key: string, buildinAlias: number | Array<number> | void) => boolean;
109109

110110
// allow dynamic method registration
111111
[key: string]: any

src/compiler/codegen/events.js

+9-14
Original file line numberDiff line numberDiff line change
@@ -74,20 +74,15 @@ function genHandler (
7474
}
7575

7676
function genKeyFilter (keys: Array<string>): string {
77-
const code = keys.length === 1
78-
? normalizeKeyCode(keys[0])
79-
: Array.prototype.concat.apply([], keys.map(normalizeKeyCode))
80-
if (Array.isArray(code)) {
81-
return `if(${code.map(c => `$event.keyCode!==${c}`).join('&&')})return;`
82-
} else {
83-
return `if($event.keyCode!==${code})return;`
84-
}
77+
const code = keys.map(genFilterCode)
78+
return `if(${code.join('&&')})return;`
8579
}
8680

87-
function normalizeKeyCode (key) {
88-
return (
89-
parseInt(key, 10) || // number keyCode
90-
keyCodes[key] || // built-in alias
91-
`_k(${JSON.stringify(key)})` // custom alias
92-
)
81+
function genFilterCode (key: number | string): string {
82+
const keyVal = parseInt(key, 10)
83+
if (keyVal) {
84+
return `$event.keyCode!==${keyVal}`
85+
}
86+
const alias = keyCodes[key]
87+
return `_k($event.keyCode,${JSON.stringify(key)}${alias ? ',' + JSON.stringify(alias) : ''})`
9388
}

src/core/instance/render.js

+12-3
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,18 @@ export function renderMixin (Vue: Class<Component>) {
238238
return data
239239
}
240240

241-
// expose v-on keyCodes
242-
Vue.prototype._k = function getKeyCodes (key: string): any {
243-
return config.keyCodes[key]
241+
// check v-on keyCodes
242+
Vue.prototype._k = function checkKeyCodes (
243+
eventKeyCode: number,
244+
key: string,
245+
buildinAlias: number | Array<number> | void
246+
): boolean {
247+
const keyCodes = config.keyCodes[key] || buildinAlias
248+
if (Array.isArray(keyCodes)) {
249+
return keyCodes.indexOf(eventKeyCode) === -1
250+
} else {
251+
return keyCodes !== eventKeyCode
252+
}
244253
}
245254
}
246255

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

+22
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,28 @@ describe('Directive v-on', () => {
187187
expect(spy).toHaveBeenCalled()
188188
})
189189

190+
it('should override build-in keyCode', () => {
191+
Vue.config.keyCodes.up = [1, 87]
192+
vm = new Vue({
193+
el,
194+
template: `<input @keyup.up="foo" @keyup.down="foo">`,
195+
methods: { foo: spy }
196+
})
197+
triggerEvent(vm.$el, 'keyup', e => {
198+
e.keyCode = 87
199+
})
200+
expect(spy).toHaveBeenCalled()
201+
triggerEvent(vm.$el, 'keyup', e => {
202+
e.keyCode = 1
203+
})
204+
expect(spy).toHaveBeenCalledTimes(2)
205+
// should not affect build-in down keycode
206+
triggerEvent(vm.$el, 'keyup', e => {
207+
e.keyCode = 40
208+
})
209+
expect(spy).toHaveBeenCalledTimes(3)
210+
})
211+
190212
it('should bind to a child component', () => {
191213
Vue.component('bar', {
192214
template: '<span>Hello</span>'

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -224,17 +224,17 @@ describe('codegen', () => {
224224
it('generate events with keycode', () => {
225225
assertCodegen(
226226
'<input @input.enter="onInput">',
227-
`with(this){return _h('input',{on:{"input":function($event){if($event.keyCode!==13)return;onInput($event)}}})}`
227+
`with(this){return _h('input',{on:{"input":function($event){if(_k($event.keyCode,"enter",13))return;onInput($event)}}})}`
228228
)
229229
// multiple keycodes (delete)
230230
assertCodegen(
231231
'<input @input.delete="onInput">',
232-
`with(this){return _h('input',{on:{"input":function($event){if($event.keyCode!==8&&$event.keyCode!==46)return;onInput($event)}}})}`
232+
`with(this){return _h('input',{on:{"input":function($event){if(_k($event.keyCode,"delete",[8,46]))return;onInput($event)}}})}`
233233
)
234234
// multiple keycodes (chained)
235235
assertCodegen(
236236
'<input @keydown.enter.delete="onInput">',
237-
`with(this){return _h('input',{on:{"keydown":function($event){if($event.keyCode!==13&&$event.keyCode!==8&&$event.keyCode!==46)return;onInput($event)}}})}`
237+
`with(this){return _h('input',{on:{"keydown":function($event){if(_k($event.keyCode,"enter",13)&&_k($event.keyCode,"delete",[8,46]))return;onInput($event)}}})}`
238238
)
239239
// number keycode
240240
assertCodegen(
@@ -244,7 +244,7 @@ describe('codegen', () => {
244244
// custom keycode
245245
assertCodegen(
246246
'<input @input.custom="onInput">',
247-
`with(this){return _h('input',{on:{"input":function($event){if($event.keyCode!==_k("custom"))return;onInput($event)}}})}`
247+
`with(this){return _h('input',{on:{"input":function($event){if(_k($event.keyCode,"custom"))return;onInput($event)}}})}`
248248
)
249249
})
250250

0 commit comments

Comments
 (0)