feat(compiler-core): support v-is
see https://github.com/vuejs/rfcs/pull/149 for details
This commit is contained in:
		
							parent
							
								
									d777ac6549
								
							
						
					
					
						commit
						b8ffbffaf7
					
				| @ -646,6 +646,55 @@ describe('compiler: parse', () => { | |||||||
|       }) |       }) | ||||||
|     }) |     }) | ||||||
| 
 | 
 | ||||||
|  |     test('v-is without `isNativeTag`', () => { | ||||||
|  |       const ast = baseParse( | ||||||
|  |         `<div></div><div v-is="'foo'"></div><Comp></Comp>`, | ||||||
|  |         { | ||||||
|  |           isNativeTag: tag => tag === 'div' | ||||||
|  |         } | ||||||
|  |       ) | ||||||
|  | 
 | ||||||
|  |       expect(ast.children[0]).toMatchObject({ | ||||||
|  |         type: NodeTypes.ELEMENT, | ||||||
|  |         tag: 'div', | ||||||
|  |         tagType: ElementTypes.ELEMENT | ||||||
|  |       }) | ||||||
|  | 
 | ||||||
|  |       expect(ast.children[1]).toMatchObject({ | ||||||
|  |         type: NodeTypes.ELEMENT, | ||||||
|  |         tag: 'div', | ||||||
|  |         tagType: ElementTypes.COMPONENT | ||||||
|  |       }) | ||||||
|  | 
 | ||||||
|  |       expect(ast.children[2]).toMatchObject({ | ||||||
|  |         type: NodeTypes.ELEMENT, | ||||||
|  |         tag: 'Comp', | ||||||
|  |         tagType: ElementTypes.COMPONENT | ||||||
|  |       }) | ||||||
|  |     }) | ||||||
|  | 
 | ||||||
|  |     test('v-is with `isNativeTag`', () => { | ||||||
|  |       const ast = baseParse(`<div></div><div v-is="'foo'"></div><Comp></Comp>`) | ||||||
|  | 
 | ||||||
|  |       expect(ast.children[0]).toMatchObject({ | ||||||
|  |         type: NodeTypes.ELEMENT, | ||||||
|  |         tag: 'div', | ||||||
|  |         tagType: ElementTypes.ELEMENT | ||||||
|  |       }) | ||||||
|  | 
 | ||||||
|  |       expect(ast.children[1]).toMatchObject({ | ||||||
|  |         type: NodeTypes.ELEMENT, | ||||||
|  |         tag: 'div', | ||||||
|  |         tagType: ElementTypes.COMPONENT | ||||||
|  |       }) | ||||||
|  | 
 | ||||||
|  |       expect(ast.children[2]).toMatchObject({ | ||||||
|  |         type: NodeTypes.ELEMENT, | ||||||
|  |         tag: 'Comp', | ||||||
|  |         tagType: ElementTypes.COMPONENT | ||||||
|  |       }) | ||||||
|  |     }) | ||||||
|  | 
 | ||||||
|     test('custom element', () => { |     test('custom element', () => { | ||||||
|       const ast = baseParse('<div></div><comp></comp>', { |       const ast = baseParse('<div></div><comp></comp>', { | ||||||
|         isNativeTag: tag => tag === 'div', |         isNativeTag: tag => tag === 'div', | ||||||
|  | |||||||
| @ -829,6 +829,25 @@ describe('compiler: element transform', () => { | |||||||
|         } |         } | ||||||
|       }) |       }) | ||||||
|     }) |     }) | ||||||
|  | 
 | ||||||
|  |     test('v-is', () => { | ||||||
|  |       const { node, root } = parseWithBind(`<div v-is="'foo'" />`) | ||||||
|  |       expect(root.helpers).toContain(RESOLVE_DYNAMIC_COMPONENT) | ||||||
|  |       expect(node).toMatchObject({ | ||||||
|  |         tag: { | ||||||
|  |           callee: RESOLVE_DYNAMIC_COMPONENT, | ||||||
|  |           arguments: [ | ||||||
|  |             { | ||||||
|  |               type: NodeTypes.SIMPLE_EXPRESSION, | ||||||
|  |               content: `'foo'`, | ||||||
|  |               isStatic: false | ||||||
|  |             } | ||||||
|  |           ] | ||||||
|  |         }, | ||||||
|  |         // should skip v-is runtime check
 | ||||||
|  |         directives: undefined | ||||||
|  |       }) | ||||||
|  |     }) | ||||||
|   }) |   }) | ||||||
| 
 | 
 | ||||||
|   test('<svg> should be forced into blocks', () => { |   test('<svg> should be forced into blocks', () => { | ||||||
|  | |||||||
| @ -451,9 +451,13 @@ function parseTag( | |||||||
|   let tagType = ElementTypes.ELEMENT |   let tagType = ElementTypes.ELEMENT | ||||||
|   const options = context.options |   const options = context.options | ||||||
|   if (!context.inPre && !options.isCustomElement(tag)) { |   if (!context.inPre && !options.isCustomElement(tag)) { | ||||||
|     if (options.isNativeTag) { |     const hasVIs = props.some( | ||||||
|  |       p => p.type === NodeTypes.DIRECTIVE && p.name === 'is' | ||||||
|  |     ) | ||||||
|  |     if (options.isNativeTag && !hasVIs) { | ||||||
|       if (!options.isNativeTag(tag)) tagType = ElementTypes.COMPONENT |       if (!options.isNativeTag(tag)) tagType = ElementTypes.COMPONENT | ||||||
|     } else if ( |     } else if ( | ||||||
|  |       hasVIs || | ||||||
|       isCoreComponent(tag) || |       isCoreComponent(tag) || | ||||||
|       (options.isBuiltInComponent && options.isBuiltInComponent(tag)) || |       (options.isBuiltInComponent && options.isBuiltInComponent(tag)) || | ||||||
|       /^[A-Z]/.test(tag) || |       /^[A-Z]/.test(tag) || | ||||||
|  | |||||||
| @ -36,7 +36,8 @@ import { | |||||||
|   toValidAssetId, |   toValidAssetId, | ||||||
|   findProp, |   findProp, | ||||||
|   isCoreComponent, |   isCoreComponent, | ||||||
|   isBindKey |   isBindKey, | ||||||
|  |   findDir | ||||||
| } from '../utils' | } from '../utils' | ||||||
| import { buildSlots } from './vSlot' | import { buildSlots } from './vSlot' | ||||||
| import { isStaticNode } from './hoistStatic' | import { isStaticNode } from './hoistStatic' | ||||||
| @ -202,7 +203,8 @@ export function resolveComponentType( | |||||||
|   const { tag } = node |   const { tag } = node | ||||||
| 
 | 
 | ||||||
|   // 1. dynamic component
 |   // 1. dynamic component
 | ||||||
|   const isProp = node.tag === 'component' && findProp(node, 'is') |   const isProp = | ||||||
|  |     node.tag === 'component' ? findProp(node, 'is') : findDir(node, 'is') | ||||||
|   if (isProp) { |   if (isProp) { | ||||||
|     const exp = |     const exp = | ||||||
|       isProp.type === NodeTypes.ATTRIBUTE |       isProp.type === NodeTypes.ATTRIBUTE | ||||||
| @ -340,8 +342,11 @@ export function buildProps( | |||||||
|       if (name === 'once') { |       if (name === 'once') { | ||||||
|         continue |         continue | ||||||
|       } |       } | ||||||
|       // skip :is on <component>
 |       // skip v-is and :is on <component>
 | ||||||
|       if (isBind && tag === 'component' && isBindKey(arg, 'is')) { |       if ( | ||||||
|  |         name === 'is' || | ||||||
|  |         (isBind && tag === 'component' && isBindKey(arg, 'is')) | ||||||
|  |       ) { | ||||||
|         continue |         continue | ||||||
|       } |       } | ||||||
|       // skip v-on in SSR compilation
 |       // skip v-on in SSR compilation
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user