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>`)
|
||||
})
|
||||
|
||||
// #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() {
|
||||
|
@ -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`)
|
||||
@ -469,6 +475,9 @@ export function createComponentInstance(
|
||||
// props default value
|
||||
propsDefaults: EMPTY_OBJ,
|
||||
|
||||
// inheritAttrs
|
||||
inheritAttrs: type.inheritAttrs,
|
||||
|
||||
// state
|
||||
ctx: EMPTY_OBJ,
|
||||
data: EMPTY_OBJ,
|
||||
|
@ -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
|
||||
@ -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(
|
||||
@ -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(
|
||||
|
@ -55,7 +55,8 @@ export function renderComponentRoot(
|
||||
renderCache,
|
||||
data,
|
||||
setupState,
|
||||
ctx
|
||||
ctx,
|
||||
inheritAttrs
|
||||
} = instance
|
||||
|
||||
let result
|
||||
@ -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) {
|
||||
@ -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,
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user