瀏覽代碼

fix: support KeyboardEvent.key in built-in keyboard event modifiers (#7121)

fix #6900
JK 8 年之前
父節點
當前提交
1c8e2e88ed
共有 2 個文件被更改,包括 54 次插入6 次删除
  1. 25 6
      src/core/instance/render-helpers/check-keycodes.js
  2. 29 0
      test/unit/features/directives/on.spec.js

+ 25 - 6
src/core/instance/render-helpers/check-keycodes.js

@@ -3,6 +3,26 @@
 import config from 'core/config'
 import { hyphenate } from 'shared/util'
 
+const keyNames: { [key: string]: string | Array<string> } = {
+  esc: 'Escape',
+  tab: 'Tab',
+  enter: 'Enter',
+  space: ' ',
+  up: 'ArrowUp',
+  left: 'ArrowLeft',
+  right: 'ArrowRight',
+  down: 'ArrowDown',
+  'delete': ['Backspace', 'Delete']
+}
+
+function isKeyNotMatch<T> (expect: T | Array<T>, actual: T): boolean {
+  if (Array.isArray(expect)) {
+    return expect.indexOf(actual) === -1
+  } else {
+    return expect !== actual
+  }
+}
+
 /**
  * Runtime helper for checking keyCodes from config.
  * exposed as Vue.prototype._k
@@ -15,12 +35,11 @@ export function checkKeyCodes (
   eventKeyName?: string
 ): ?boolean {
   const keyCodes = config.keyCodes[key] || builtInAlias
-  if (keyCodes) {
-    if (Array.isArray(keyCodes)) {
-      return keyCodes.indexOf(eventKeyCode) === -1
-    } else {
-      return keyCodes !== eventKeyCode
-    }
+  const builtInName: string | Array<string> = keyNames[key]
+  if (builtInName && keyCodes === builtInAlias && eventKeyName) {
+    return isKeyNotMatch(builtInName, eventKeyName)
+  } else if (keyCodes) {
+    return isKeyNotMatch(keyCodes, eventKeyCode)
   } else if (eventKeyName) {
     return hyphenate(eventKeyName) !== key
   }

+ 29 - 0
test/unit/features/directives/on.spec.js

@@ -362,6 +362,35 @@ describe('Directive v-on', () => {
     expect(spyMiddle).toHaveBeenCalled()
   })
 
+  it('should support KeyboardEvent.key for built in aliases', () => {
+    vm = new Vue({
+      el,
+      template: `
+        <div>
+          <input ref="enter" @keyup.enter="foo">
+          <input ref="space" @keyup.space="foo">
+          <input ref="esc" @keyup.esc="foo">
+          <input ref="left" @keyup.left="foo">
+          <input ref="delete" @keyup.delete="foo">
+        </div>
+      `,
+      methods: { foo: spy }
+    })
+
+    triggerEvent(vm.$refs.enter, 'keyup', e => { e.key = 'Enter' })
+    expect(spy.calls.count()).toBe(1)
+    triggerEvent(vm.$refs.space, 'keyup', e => { e.key = ' ' })
+    expect(spy.calls.count()).toBe(2)
+    triggerEvent(vm.$refs.esc, 'keyup', e => { e.key = 'Escape' })
+    expect(spy.calls.count()).toBe(3)
+    triggerEvent(vm.$refs.left, 'keyup', e => { e.key = 'ArrowLeft' })
+    expect(spy.calls.count()).toBe(4)
+    triggerEvent(vm.$refs.delete, 'keyup', e => { e.key = 'Backspace' })
+    expect(spy.calls.count()).toBe(5)
+    triggerEvent(vm.$refs.delete, 'keyup', e => { e.key = 'Delete' })
+    expect(spy.calls.count()).toBe(6)
+  })
+
   it('should support custom keyCode', () => {
     Vue.config.keyCodes.test = 1
     vm = new Vue({