fix(sfc/scoped-style): inherit scopeId through nested HOCs with inheritAttrs: false
fix #1988
This commit is contained in:
@@ -34,7 +34,7 @@ describe('scopeId runtime support', () => {
|
||||
const root = nodeOps.createElement('div')
|
||||
render(h(App), root)
|
||||
expect(serializeInner(root)).toBe(
|
||||
`<div parent><div parent child></div></div>`
|
||||
`<div parent><div child parent></div></div>`
|
||||
)
|
||||
})
|
||||
|
||||
@@ -67,14 +67,39 @@ describe('scopeId runtime support', () => {
|
||||
// - scopeId from parent
|
||||
// - slotted scopeId (with `-s` postfix) from child (the tree owner)
|
||||
expect(serializeInner(root)).toBe(
|
||||
`<div parent child>` +
|
||||
`<div child parent>` +
|
||||
`<div parent child-s></div>` +
|
||||
// component inside slot should have:
|
||||
// - scopeId from template context
|
||||
// - slotted scopeId from slot owner
|
||||
// - its own scopeId
|
||||
`<span parent child-s child2></span>` +
|
||||
`<span child2 parent child-s></span>` +
|
||||
`</div>`
|
||||
)
|
||||
})
|
||||
|
||||
// #1988
|
||||
test('should inherit scopeId through nested HOCs with inheritAttrs: false', () => {
|
||||
const withParentId = withScopeId('parent')
|
||||
const App = {
|
||||
__scopeId: 'parent',
|
||||
render: withParentId(() => {
|
||||
return h(Child)
|
||||
})
|
||||
}
|
||||
|
||||
function Child() {
|
||||
return h(Child2, { class: 'foo' })
|
||||
}
|
||||
|
||||
function Child2() {
|
||||
return h('div')
|
||||
}
|
||||
Child2.inheritAttrs = false
|
||||
|
||||
const root = nodeOps.createElement('div')
|
||||
render(h(App), root)
|
||||
|
||||
expect(serializeInner(root)).toBe(`<div parent></div>`)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -42,7 +42,6 @@ export function renderComponentRoot(
|
||||
): VNode {
|
||||
const {
|
||||
type: Component,
|
||||
parent,
|
||||
vnode,
|
||||
proxy,
|
||||
withProxy,
|
||||
@@ -172,22 +171,6 @@ export function renderComponentRoot(
|
||||
}
|
||||
}
|
||||
|
||||
// inherit scopeId
|
||||
const scopeId = vnode.scopeId
|
||||
// vite#536: if subtree root is created from parent slot if would already
|
||||
// have the correct scopeId, in this case adding the scopeId will cause
|
||||
// it to be removed if the original slot vnode is reused.
|
||||
const needScopeId = scopeId && root.scopeId !== scopeId
|
||||
const treeOwnerId = parent && parent.type.__scopeId
|
||||
const slotScopeId =
|
||||
treeOwnerId && treeOwnerId !== scopeId ? treeOwnerId + '-s' : null
|
||||
if (needScopeId || slotScopeId) {
|
||||
const extras: Data = {}
|
||||
if (needScopeId) extras[scopeId!] = ''
|
||||
if (slotScopeId) extras[slotScopeId] = ''
|
||||
root = cloneVNode(root, extras)
|
||||
}
|
||||
|
||||
// inherit directives
|
||||
if (vnode.dirs) {
|
||||
if (__DEV__ && !isElementRoot(root)) {
|
||||
|
||||
@@ -745,15 +745,31 @@ function baseCreateRenderer(
|
||||
}
|
||||
}
|
||||
// scopeId
|
||||
if (scopeId) {
|
||||
hostSetScopeId(el, scopeId)
|
||||
}
|
||||
const treeOwnerId = parentComponent && parentComponent.type.__scopeId
|
||||
// vnode's own scopeId and the current patched component's scopeId is
|
||||
// different - this is a slot content node.
|
||||
if (treeOwnerId && treeOwnerId !== scopeId) {
|
||||
hostSetScopeId(el, treeOwnerId + '-s')
|
||||
}
|
||||
setScopeId(el, scopeId, vnode, parentComponent)
|
||||
// if (scopeId) {
|
||||
// hostSetScopeId(el, scopeId)
|
||||
// }
|
||||
// if (parentComponent) {
|
||||
// const treeOwnerId = parentComponent.type.__scopeId
|
||||
// // vnode's own scopeId and the current patched component's scopeId is
|
||||
// // different - this is a slot content node.
|
||||
// if (treeOwnerId && treeOwnerId !== scopeId) {
|
||||
// hostSetScopeId(el, treeOwnerId + '-s')
|
||||
// }
|
||||
// const parentScopeId =
|
||||
// vnode === parentComponent.subTree && parentComponent.vnode.scopeId
|
||||
// if (parentScopeId) {
|
||||
// hostSetScopeId(el, parentScopeId)
|
||||
// if (parentComponent.parent) {
|
||||
// const treeOwnerId = parentComponent.parent.type.__scopeId
|
||||
// // vnode's own scopeId and the current patched component's scopeId is
|
||||
// // different - this is a slot content node.
|
||||
// if (treeOwnerId && treeOwnerId !== parentScopeId) {
|
||||
// hostSetScopeId(el, treeOwnerId + '-s')
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
|
||||
Object.defineProperty(el, '__vnode', {
|
||||
@@ -791,6 +807,33 @@ function baseCreateRenderer(
|
||||
}
|
||||
}
|
||||
|
||||
const setScopeId = (
|
||||
el: RendererElement,
|
||||
scopeId: string | false | null,
|
||||
vnode: VNode,
|
||||
parentComponent: ComponentInternalInstance | null
|
||||
) => {
|
||||
if (scopeId) {
|
||||
hostSetScopeId(el, scopeId)
|
||||
}
|
||||
if (parentComponent) {
|
||||
const treeOwnerId = parentComponent.type.__scopeId
|
||||
// vnode's own scopeId and the current patched component's scopeId is
|
||||
// different - this is a slot content node.
|
||||
if (treeOwnerId && treeOwnerId !== scopeId) {
|
||||
hostSetScopeId(el, treeOwnerId + '-s')
|
||||
}
|
||||
if (vnode === parentComponent.subTree) {
|
||||
setScopeId(
|
||||
el,
|
||||
parentComponent.vnode.scopeId,
|
||||
parentComponent.vnode,
|
||||
parentComponent.parent
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const mountChildren: MountChildrenFn = (
|
||||
children,
|
||||
container,
|
||||
|
||||
Reference in New Issue
Block a user