fix(runtime-core): fix resolving inheritAttrs from mixins (#3742)
fix #3741
This commit is contained in:
		
							parent
							
								
									9b2e894017
								
							
						
					
					
						commit
						d6607c9864
					
				| @ -301,6 +301,34 @@ describe('attribute fallthrough', () => { | |||||||
|     expect(root.innerHTML).toMatch(`<div>1</div>`) |     expect(root.innerHTML).toMatch(`<div>1</div>`) | ||||||
|   }) |   }) | ||||||
| 
 | 
 | ||||||
|  |   // #3741
 | ||||||
|  |   it('should not fallthrough with inheritAttrs: false from mixins', () => { | ||||||
|  |     const Parent = { | ||||||
|  |       render() { | ||||||
|  |         return h(Child, { foo: 1, class: 'parent' }) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     const mixin = { | ||||||
|  |       inheritAttrs: false | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     const Child = defineComponent({ | ||||||
|  |       mixins: [mixin], | ||||||
|  |       props: ['foo'], | ||||||
|  |       render() { | ||||||
|  |         return h('div', this.foo) | ||||||
|  |       } | ||||||
|  |     }) | ||||||
|  | 
 | ||||||
|  |     const root = document.createElement('div') | ||||||
|  |     document.body.appendChild(root) | ||||||
|  |     render(h(Parent), root) | ||||||
|  | 
 | ||||||
|  |     // should not contain class
 | ||||||
|  |     expect(root.innerHTML).toMatch(`<div>1</div>`) | ||||||
|  |   }) | ||||||
|  | 
 | ||||||
|   it('explicit spreading with inheritAttrs: false', () => { |   it('explicit spreading with inheritAttrs: false', () => { | ||||||
|     const Parent = { |     const Parent = { | ||||||
|       render() { |       render() { | ||||||
|  | |||||||
| @ -285,6 +285,12 @@ export interface ComponentInternalInstance { | |||||||
|    */ |    */ | ||||||
|   emitsOptions: ObjectEmitsOptions | null |   emitsOptions: ObjectEmitsOptions | null | ||||||
| 
 | 
 | ||||||
|  |   /** | ||||||
|  |    * resolved inheritAttrs options | ||||||
|  |    * @internal | ||||||
|  |    */ | ||||||
|  |   inheritAttrs?: boolean | ||||||
|  | 
 | ||||||
|   // the rest are only for stateful components ---------------------------------
 |   // the rest are only for stateful components ---------------------------------
 | ||||||
| 
 | 
 | ||||||
|   // main proxy that serves as the public instance (`this`)
 |   // main proxy that serves as the public instance (`this`)
 | ||||||
| @ -469,6 +475,9 @@ export function createComponentInstance( | |||||||
|     // props default value
 |     // props default value
 | ||||||
|     propsDefaults: EMPTY_OBJ, |     propsDefaults: EMPTY_OBJ, | ||||||
| 
 | 
 | ||||||
|  |     // inheritAttrs
 | ||||||
|  |     inheritAttrs: type.inheritAttrs, | ||||||
|  | 
 | ||||||
|     // state
 |     // state
 | ||||||
|     ctx: EMPTY_OBJ, |     ctx: EMPTY_OBJ, | ||||||
|     data: EMPTY_OBJ, |     data: EMPTY_OBJ, | ||||||
|  | |||||||
| @ -567,17 +567,14 @@ export function applyOptions( | |||||||
|     errorCaptured, |     errorCaptured, | ||||||
|     serverPrefetch, |     serverPrefetch, | ||||||
|     // public API
 |     // public API
 | ||||||
|     expose |     expose, | ||||||
|  |     inheritAttrs | ||||||
|   } = options |   } = options | ||||||
| 
 | 
 | ||||||
|   const publicThis = instance.proxy! |   const publicThis = instance.proxy! | ||||||
|   const ctx = instance.ctx |   const ctx = instance.ctx | ||||||
|   const globalMixins = instance.appContext.mixins |   const globalMixins = instance.appContext.mixins | ||||||
| 
 | 
 | ||||||
|   if (asMixin && render && instance.render === NOOP) { |  | ||||||
|     instance.render = render as InternalRenderFunction |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   // applyOptions is called non-as-mixin once per instance
 |   // applyOptions is called non-as-mixin once per instance
 | ||||||
|   if (!asMixin) { |   if (!asMixin) { | ||||||
|     shouldCacheAccess = false |     shouldCacheAccess = false | ||||||
| @ -755,17 +752,6 @@ export function applyOptions( | |||||||
|     }) |     }) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   // asset options.
 |  | ||||||
|   // To reduce memory usage, only components with mixins or extends will have
 |  | ||||||
|   // resolved asset registry attached to instance.
 |  | ||||||
|   if (asMixin) { |  | ||||||
|     resolveInstanceAssets(instance, options, COMPONENTS) |  | ||||||
|     resolveInstanceAssets(instance, options, DIRECTIVES) |  | ||||||
|     if (__COMPAT__ && isCompatEnabled(DeprecationTypes.FILTERS, instance)) { |  | ||||||
|       resolveInstanceAssets(instance, options, FILTERS) |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   // lifecycle options
 |   // lifecycle options
 | ||||||
|   if (!asMixin) { |   if (!asMixin) { | ||||||
|     callSyncHook( |     callSyncHook( | ||||||
| @ -831,6 +817,27 @@ export function applyOptions( | |||||||
|       warn(`The \`expose\` option is ignored when used in mixins.`) |       warn(`The \`expose\` option is ignored when used in mixins.`) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | 
 | ||||||
|  |   // options that are handled when creating the instance but also need to be
 | ||||||
|  |   // applied from mixins
 | ||||||
|  |   if (asMixin) { | ||||||
|  |     if (render && instance.render === NOOP) { | ||||||
|  |       instance.render = render as InternalRenderFunction | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (inheritAttrs != null && instance.type.inheritAttrs == null) { | ||||||
|  |       instance.inheritAttrs = inheritAttrs | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // asset options.
 | ||||||
|  |     // To reduce memory usage, only components with mixins or extends will have
 | ||||||
|  |     // resolved asset registry attached to instance.
 | ||||||
|  |     resolveInstanceAssets(instance, options, COMPONENTS) | ||||||
|  |     resolveInstanceAssets(instance, options, DIRECTIVES) | ||||||
|  |     if (__COMPAT__ && isCompatEnabled(DeprecationTypes.FILTERS, instance)) { | ||||||
|  |       resolveInstanceAssets(instance, options, FILTERS) | ||||||
|  |     } | ||||||
|  |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function resolveInstanceAssets( | function resolveInstanceAssets( | ||||||
|  | |||||||
| @ -55,7 +55,8 @@ export function renderComponentRoot( | |||||||
|     renderCache, |     renderCache, | ||||||
|     data, |     data, | ||||||
|     setupState, |     setupState, | ||||||
|     ctx |     ctx, | ||||||
|  |     inheritAttrs | ||||||
|   } = instance |   } = instance | ||||||
| 
 | 
 | ||||||
|   let result |   let result | ||||||
| @ -123,7 +124,7 @@ export function renderComponentRoot( | |||||||
|       ;[root, setRoot] = getChildRoot(result) |       ;[root, setRoot] = getChildRoot(result) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (fallthroughAttrs && Component.inheritAttrs !== false) { |     if (fallthroughAttrs && inheritAttrs !== false) { | ||||||
|       const keys = Object.keys(fallthroughAttrs) |       const keys = Object.keys(fallthroughAttrs) | ||||||
|       const { shapeFlag } = root |       const { shapeFlag } = root | ||||||
|       if (keys.length) { |       if (keys.length) { | ||||||
| @ -190,7 +191,7 @@ export function renderComponentRoot( | |||||||
|     ) { |     ) { | ||||||
|       const { class: cls, style } = vnode.props || {} |       const { class: cls, style } = vnode.props || {} | ||||||
|       if (cls || style) { |       if (cls || style) { | ||||||
|         if (__DEV__ && Component.inheritAttrs === false) { |         if (__DEV__ && inheritAttrs === false) { | ||||||
|           warnDeprecation( |           warnDeprecation( | ||||||
|             DeprecationTypes.INSTANCE_ATTRS_CLASS_STYLE, |             DeprecationTypes.INSTANCE_ATTRS_CLASS_STYLE, | ||||||
|             instance, |             instance, | ||||||
|  | |||||||
| @ -132,8 +132,7 @@ function renderComponentSubTree( | |||||||
|     if (ssrRender) { |     if (ssrRender) { | ||||||
|       // optimized
 |       // optimized
 | ||||||
|       // resolve fallthrough attrs
 |       // resolve fallthrough attrs
 | ||||||
|       let attrs = |       let attrs = instance.inheritAttrs !== false ? instance.attrs : undefined | ||||||
|         instance.type.inheritAttrs !== false ? instance.attrs : undefined |  | ||||||
|       let hasCloned = false |       let hasCloned = false | ||||||
| 
 | 
 | ||||||
|       let cur = instance |       let cur = instance | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user