Skip to content

Commit

Permalink
fix(sfc/scoped-style): inherit scopeId through nested HOCs with inher…
Browse files Browse the repository at this point in the history
…itAttrs: false

fix #1988
  • Loading branch information
yyx990803 committed Sep 1, 2020
1 parent 5b82c48 commit c0427b4
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 42 deletions.
31 changes: 28 additions & 3 deletions packages/runtime-core/__tests__/helpers/scopeId.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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>`
)
})

Expand Down Expand Up @@ -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>`)
})
})
17 changes: 0 additions & 17 deletions packages/runtime-core/src/componentRenderUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ export function renderComponentRoot(
): VNode {
const {
type: Component,
parent,
vnode,
proxy,
withProxy,
Expand Down Expand Up @@ -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)) {
Expand Down
61 changes: 52 additions & 9 deletions packages/runtime-core/src/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', {
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion packages/server-renderer/__tests__/renderToStream.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ describe('ssr: renderToStream', () => {
}

expect(await renderToStream(h(Parent))).toBe(
`<div data-v-test data-v-child><span data-v-test data-v-child-s>slot</span></div>`
`<div data-v-child data-v-test><span data-v-test data-v-child-s>slot</span></div>`
)
})
})
Expand Down
2 changes: 1 addition & 1 deletion packages/server-renderer/__tests__/renderToString.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ describe('ssr: renderToString', () => {
}

expect(await renderToString(h(Parent))).toBe(
`<div data-v-test data-v-child><span data-v-test data-v-child-s>slot</span></div>`
`<div data-v-child data-v-test><span data-v-test data-v-child-s>slot</span></div>`
)
})
})
Expand Down
49 changes: 38 additions & 11 deletions packages/server-renderer/src/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,11 @@ function renderComponentSubTree(
const comp = instance.type as Component
const { getBuffer, push } = createBuffer()
if (isFunction(comp)) {
renderVNode(push, renderComponentRoot(instance), instance)
renderVNode(
push,
(instance.subTree = renderComponentRoot(instance)),
instance
)
} else {
if (!instance.render && !comp.ssrRender && isString(comp.template)) {
comp.ssrRender = ssrCompile(comp.template, instance)
Expand Down Expand Up @@ -139,7 +143,11 @@ function renderComponentSubTree(
)
setCurrentRenderingInstance(null)
} else if (instance.render) {
renderVNode(push, renderComponentRoot(instance), instance)
renderVNode(
push,
(instance.subTree = renderComponentRoot(instance)),
instance
)
} else {
warn(
`Component ${
Expand Down Expand Up @@ -225,15 +233,7 @@ function renderElementVNode(
openTag += ssrRenderAttrs(props, tag)
}

if (scopeId) {
openTag += ` ${scopeId}`
const treeOwnerId = parentComponent && parentComponent.type.__scopeId
// vnode's own scopeId and the current rendering component's scopeId is
// different - this is a slot content node.
if (treeOwnerId && treeOwnerId !== scopeId) {
openTag += ` ${treeOwnerId}-s`
}
}
openTag += resolveScopeId(scopeId, vnode, parentComponent)

push(openTag + `>`)
if (!isVoidTag(tag)) {
Expand Down Expand Up @@ -265,6 +265,33 @@ function renderElementVNode(
}
}

function resolveScopeId(
scopeId: string | null,
vnode: VNode,
parentComponent: ComponentInternalInstance | null
) {
let res = ``
if (scopeId) {
res = ` ${scopeId}`
}
if (parentComponent) {
const treeOwnerId = parentComponent.type.__scopeId
// vnode's own scopeId and the current rendering component's scopeId is
// different - this is a slot content node.
if (treeOwnerId && treeOwnerId !== scopeId) {
res += ` ${treeOwnerId}-s`
}
if (vnode === parentComponent.subTree) {
res += resolveScopeId(
parentComponent.vnode.scopeId,
parentComponent.vnode,
parentComponent.parent
)
}
}
return res
}

function applySSRDirectives(
vnode: VNode,
rawProps: VNodeProps | null,
Expand Down

0 comments on commit c0427b4

Please sign in to comment.