Skip to content

Commit

Permalink
fix(runtime-core): fix resolving inheritAttrs from mixins (#3742)
Browse files Browse the repository at this point in the history
fix #3741
  • Loading branch information
edison1105 authored May 28, 2021
1 parent 9b2e894 commit d6607c9
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 21 deletions.
28 changes: 28 additions & 0 deletions packages/runtime-core/__tests__/rendererAttrsFallthrough.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,34 @@ describe('attribute fallthrough', () => {
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', () => {
const Parent = {
render() {
Expand Down
9 changes: 9 additions & 0 deletions packages/runtime-core/src/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,12 @@ export interface ComponentInternalInstance {
*/
emitsOptions: ObjectEmitsOptions | null

/**
* resolved inheritAttrs options
* @internal
*/
inheritAttrs?: boolean

// the rest are only for stateful components ---------------------------------

// main proxy that serves as the public instance (`this`)
Expand Down Expand Up @@ -469,6 +475,9 @@ export function createComponentInstance(
// props default value
propsDefaults: EMPTY_OBJ,

// inheritAttrs
inheritAttrs: type.inheritAttrs,

// state
ctx: EMPTY_OBJ,
data: EMPTY_OBJ,
Expand Down
39 changes: 23 additions & 16 deletions packages/runtime-core/src/componentOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -567,17 +567,14 @@ export function applyOptions(
errorCaptured,
serverPrefetch,
// public API
expose
expose,
inheritAttrs
} = options

const publicThis = instance.proxy!
const ctx = instance.ctx
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
if (!asMixin) {
shouldCacheAccess = false
Expand Down Expand Up @@ -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
if (!asMixin) {
callSyncHook(
Expand Down Expand Up @@ -831,6 +817,27 @@ export function applyOptions(
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(
Expand Down
7 changes: 4 additions & 3 deletions packages/runtime-core/src/componentRenderUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ export function renderComponentRoot(
renderCache,
data,
setupState,
ctx
ctx,
inheritAttrs
} = instance

let result
Expand Down Expand Up @@ -123,7 +124,7 @@ export function renderComponentRoot(
;[root, setRoot] = getChildRoot(result)
}

if (fallthroughAttrs && Component.inheritAttrs !== false) {
if (fallthroughAttrs && inheritAttrs !== false) {
const keys = Object.keys(fallthroughAttrs)
const { shapeFlag } = root
if (keys.length) {
Expand Down Expand Up @@ -190,7 +191,7 @@ export function renderComponentRoot(
) {
const { class: cls, style } = vnode.props || {}
if (cls || style) {
if (__DEV__ && Component.inheritAttrs === false) {
if (__DEV__ && inheritAttrs === false) {
warnDeprecation(
DeprecationTypes.INSTANCE_ATTRS_CLASS_STYLE,
instance,
Expand Down
3 changes: 1 addition & 2 deletions packages/server-renderer/src/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,7 @@ function renderComponentSubTree(
if (ssrRender) {
// optimized
// resolve fallthrough attrs
let attrs =
instance.type.inheritAttrs !== false ? instance.attrs : undefined
let attrs = instance.inheritAttrs !== false ? instance.attrs : undefined
let hasCloned = false

let cur = instance
Expand Down

0 comments on commit d6607c9

Please sign in to comment.