mirror of https://github.com/vuejs/vue.git
prohibit replacing Vue.config + support custom keyCodes
This commit is contained in:
parent
63da54ddee
commit
4fe51a75a9
|
@ -57,6 +57,7 @@ declare interface Component {
|
||||||
_isBeingDestroyed: boolean;
|
_isBeingDestroyed: boolean;
|
||||||
_vnode: ?VNode;
|
_vnode: ?VNode;
|
||||||
_staticTrees: ?Array<VNode>;
|
_staticTrees: ?Array<VNode>;
|
||||||
|
_keyCode: (key: string) => ?number;
|
||||||
|
|
||||||
// private methods
|
// private methods
|
||||||
// lifecycle
|
// lifecycle
|
||||||
|
|
|
@ -53,10 +53,13 @@ function genHandler (
|
||||||
}
|
}
|
||||||
|
|
||||||
function genKeyFilter (key: string): string {
|
function genKeyFilter (key: string): string {
|
||||||
const code = keyCodes[key] || JSON.stringify(key)
|
const code =
|
||||||
|
parseInt(key, 10) || // number keyCode
|
||||||
|
keyCodes[key] || // built-in alias
|
||||||
|
`_keyCode(${JSON.stringify(key)})` // custom alias
|
||||||
if (Array.isArray(code)) {
|
if (Array.isArray(code)) {
|
||||||
return `if(${code.map(c => `$event.keyCode!=${c}`).join('&&')})return;`
|
return `if(${code.map(c => `$event.keyCode!==${c}`).join('&&')})return;`
|
||||||
} else {
|
} else {
|
||||||
return `if($event.keyCode!=${code})return;`
|
return `if($event.keyCode!==${code})return;`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,17 @@
|
||||||
import { no } from 'shared/util'
|
import { no } from 'shared/util'
|
||||||
|
|
||||||
export type Config = {
|
export type Config = {
|
||||||
|
// user
|
||||||
optionMergeStrategies: { [key: string]: Function },
|
optionMergeStrategies: { [key: string]: Function },
|
||||||
silent: boolean,
|
silent: boolean,
|
||||||
errorHandler: ?Function,
|
errorHandler: ?Function,
|
||||||
ignoredElements: ?Array<string>,
|
ignoredElements: ?Array<string>,
|
||||||
|
keyCodes: { [key: string]: number },
|
||||||
|
// platform
|
||||||
isReservedTag: (x?: string) => boolean,
|
isReservedTag: (x?: string) => boolean,
|
||||||
isUnknownElement: (x?: string) => boolean,
|
isUnknownElement: (x?: string) => boolean,
|
||||||
mustUseProp: (x?: string) => boolean,
|
mustUseProp: (x?: string) => boolean,
|
||||||
|
// internal
|
||||||
_assetTypes: Array<string>,
|
_assetTypes: Array<string>,
|
||||||
_lifecycleHooks: Array<string>,
|
_lifecycleHooks: Array<string>,
|
||||||
_maxUpdateCount: number,
|
_maxUpdateCount: number,
|
||||||
|
@ -38,6 +42,11 @@ const config: Config = {
|
||||||
*/
|
*/
|
||||||
ignoredElements: null,
|
ignoredElements: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom user key aliases for v-on
|
||||||
|
*/
|
||||||
|
keyCodes: Object.create(null),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a tag is reserved so that it cannot be registered as a
|
* Check if a tag is reserved so that it cannot be registered as a
|
||||||
* component. This is platform-dependent and may be overwritten.
|
* component. This is platform-dependent and may be overwritten.
|
||||||
|
|
|
@ -10,7 +10,17 @@ import { set, del } from '../observer/index'
|
||||||
import builtInComponents from '../components/index'
|
import builtInComponents from '../components/index'
|
||||||
|
|
||||||
export function initGlobalAPI (Vue: GlobalAPI) {
|
export function initGlobalAPI (Vue: GlobalAPI) {
|
||||||
Vue.config = config
|
// config
|
||||||
|
const configDef = {}
|
||||||
|
configDef.get = () => config
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
configDef.set = () => {
|
||||||
|
util.warn(
|
||||||
|
'Do not replace the Vue.config object, set individual fields instead.'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Object.defineProperty(Vue, 'config', configDef)
|
||||||
Vue.util = util
|
Vue.util = util
|
||||||
Vue.set = set
|
Vue.set = set
|
||||||
Vue.delete = del
|
Vue.delete = del
|
||||||
|
|
|
@ -152,6 +152,9 @@ export function renderMixin (Vue: Class<Component>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// expose v-on keyCodes
|
||||||
|
Vue.prototype._keyCode = key => config.keyCodes[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveSlots (
|
function resolveSlots (
|
||||||
|
|
|
@ -126,6 +126,19 @@ describe('Directive v-on', () => {
|
||||||
expect(spy).toHaveBeenCalled()
|
expect(spy).toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should support custom keyCode', () => {
|
||||||
|
Vue.config.keyCodes.test = 1
|
||||||
|
vm = new Vue({
|
||||||
|
el,
|
||||||
|
template: `<input @keyup.test="foo">`,
|
||||||
|
methods: { foo: spy }
|
||||||
|
})
|
||||||
|
triggerEvent(vm.$el, 'keyup', e => {
|
||||||
|
e.keyCode = 1
|
||||||
|
})
|
||||||
|
expect(spy).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
it('should bind to a child component', () => {
|
it('should bind to a child component', () => {
|
||||||
Vue.component('bar', {
|
Vue.component('bar', {
|
||||||
template: '<span>Hello</span>'
|
template: '<span>Hello</span>'
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
|
|
||||||
describe('Global config', () => {
|
describe('Global config', () => {
|
||||||
|
it('should warn replacing config object', () => {
|
||||||
|
const originalConfig = Vue.config
|
||||||
|
Vue.config = {}
|
||||||
|
expect(Vue.config).toBe(originalConfig)
|
||||||
|
expect('Do not replace the Vue.config object').toHaveBeenWarned()
|
||||||
|
})
|
||||||
|
|
||||||
describe('silent', () => {
|
describe('silent', () => {
|
||||||
it('should be false by default', () => {
|
it('should be false by default', () => {
|
||||||
Vue.util.warn('foo')
|
Vue.util.warn('foo')
|
||||||
|
|
|
@ -216,17 +216,22 @@ describe('codegen', () => {
|
||||||
it('generate events with keycode', () => {
|
it('generate events with keycode', () => {
|
||||||
assertCodegen(
|
assertCodegen(
|
||||||
'<input @input.enter="onInput">',
|
'<input @input.enter="onInput">',
|
||||||
`with(this){return _h(_e('input',{on:{"input":function($event){if($event.keyCode!=13)return;onInput($event)}}}))}`
|
`with(this){return _h(_e('input',{on:{"input":function($event){if($event.keyCode!==13)return;onInput($event)}}}))}`
|
||||||
)
|
)
|
||||||
// multiple keycodes (delete)
|
// multiple keycodes (delete)
|
||||||
assertCodegen(
|
assertCodegen(
|
||||||
'<input @input.delete="onInput">',
|
'<input @input.delete="onInput">',
|
||||||
`with(this){return _h(_e('input',{on:{"input":function($event){if($event.keyCode!=8&&$event.keyCode!=46)return;onInput($event)}}}))}`
|
`with(this){return _h(_e('input',{on:{"input":function($event){if($event.keyCode!==8&&$event.keyCode!==46)return;onInput($event)}}}))}`
|
||||||
)
|
)
|
||||||
// number keycode
|
// number keycode
|
||||||
assertCodegen(
|
assertCodegen(
|
||||||
'<input @input.13="onInput">',
|
'<input @input.13="onInput">',
|
||||||
`with(this){return _h(_e('input',{on:{"input":function($event){if($event.keyCode!="13")return;onInput($event)}}}))}`
|
`with(this){return _h(_e('input',{on:{"input":function($event){if($event.keyCode!==13)return;onInput($event)}}}))}`
|
||||||
|
)
|
||||||
|
// custom keycode
|
||||||
|
assertCodegen(
|
||||||
|
'<input @input.custom="onInput">',
|
||||||
|
`with(this){return _h(_e('input',{on:{"input":function($event){if($event.keyCode!==_keyCode("custom"))return;onInput($event)}}}))}`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue