feat(core): validate directives names (#326)
This commit is contained in:
		
							parent
							
								
									60961ef5b6
								
							
						
					
					
						commit
						2238925fbe
					
				| @ -138,6 +138,11 @@ describe('api: createApp', () => { | ||||
|     expect(spy1).toHaveBeenCalled() | ||||
|     expect(spy2).not.toHaveBeenCalled() | ||||
|     expect(spy3).toHaveBeenCalled() | ||||
| 
 | ||||
|     app.directive('bind', FooBar) | ||||
|     expect( | ||||
|       `Do not use built-in directive ids as custom directive id: bind` | ||||
|     ).toHaveBeenWarned() | ||||
|   }) | ||||
| 
 | ||||
|   test('mixin', () => { | ||||
| @ -342,6 +347,33 @@ describe('api: createApp', () => { | ||||
|       ).toHaveBeenWarned() | ||||
|     }) | ||||
| 
 | ||||
|     test('Component.directives', () => { | ||||
|       const app = createApp() | ||||
|       Object.defineProperty(app.config, 'isNativeTag', { | ||||
|         value: isNativeTag, | ||||
|         writable: false | ||||
|       }) | ||||
| 
 | ||||
|       const Root = { | ||||
|         directives: { | ||||
|           bind: () => {} | ||||
|         }, | ||||
|         setup() { | ||||
|           return { | ||||
|             count: ref(0) | ||||
|           } | ||||
|         }, | ||||
|         render() { | ||||
|           return null | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|       app.mount(Root, nodeOps.createElement('div')) | ||||
|       expect( | ||||
|         `Do not use built-in directive ids as custom directive id: bind` | ||||
|       ).toHaveBeenWarned() | ||||
|     }) | ||||
| 
 | ||||
|     test('register using app.component', () => { | ||||
|       const app = createApp() | ||||
|       Object.defineProperty(app.config, 'isNativeTag', { | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| import { Component, Data, validateComponentName } from './component' | ||||
| import { ComponentOptions } from './apiOptions' | ||||
| import { ComponentPublicInstance } from './componentProxy' | ||||
| import { Directive } from './directives' | ||||
| import { Directive, validateDirectiveName } from './directives' | ||||
| import { RootRenderFunction } from './createRenderer' | ||||
| import { InjectionKey } from './apiInject' | ||||
| import { isFunction, NO } from '@vue/shared' | ||||
| @ -127,7 +127,10 @@ export function createAppAPI<HostNode, HostElement>( | ||||
|       }, | ||||
| 
 | ||||
|       directive(name: string, directive?: Directive) { | ||||
|         // TODO directive name validation
 | ||||
|         if (__DEV__) { | ||||
|           validateDirectiveName(name) | ||||
|         } | ||||
| 
 | ||||
|         if (!directive) { | ||||
|           return context.directives[name] as any | ||||
|         } else { | ||||
|  | ||||
| @ -13,7 +13,7 @@ import { | ||||
|   callWithAsyncErrorHandling | ||||
| } from './errorHandling' | ||||
| import { AppContext, createAppContext, AppConfig } from './apiApp' | ||||
| import { Directive } from './directives' | ||||
| import { Directive, validateDirectiveName } from './directives' | ||||
| import { applyOptions, ComponentOptions } from './apiOptions' | ||||
| import { | ||||
|   EMPTY_OBJ, | ||||
| @ -256,6 +256,12 @@ export function setupStatefulComponent( | ||||
|         validateComponentName(name, instance.appContext.config) | ||||
|       } | ||||
|     } | ||||
|     if (Component.directives) { | ||||
|       const names = Object.keys(Component.directives) | ||||
|       for (let i = 0; i < names.length; i++) { | ||||
|         validateDirectiveName(names[i]) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   // 0. create render proxy property access cache
 | ||||
|   instance.accessCache = {} | ||||
|  | ||||
| @ -12,7 +12,7 @@ return applyDirectives(h(comp), [ | ||||
| */ | ||||
| 
 | ||||
| import { VNode, cloneVNode } from './vnode' | ||||
| import { extend, isArray, isFunction, EMPTY_OBJ } from '@vue/shared' | ||||
| import { extend, isArray, isFunction, EMPTY_OBJ, makeMap } from '@vue/shared' | ||||
| import { warn } from './warning' | ||||
| import { ComponentInternalInstance } from './component' | ||||
| import { currentRenderingInstance } from './componentRenderUtils' | ||||
| @ -51,6 +51,16 @@ type DirectiveModifiers = Record<string, boolean> | ||||
| 
 | ||||
| const valueCache = new WeakMap<Directive, WeakMap<any, any>>() | ||||
| 
 | ||||
| const isBuiltInDirective = /*#__PURE__*/ makeMap( | ||||
|   'bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text' | ||||
| ) | ||||
| 
 | ||||
| export function validateDirectiveName(name: string) { | ||||
|   if (isBuiltInDirective(name)) { | ||||
|     warn('Do not use built-in directive ids as custom directive id: ' + name) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| function applyDirective( | ||||
|   props: Record<any, any>, | ||||
|   instance: ComponentInternalInstance, | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user