Skip to content

Commit

Permalink
fix(teleport/css-v-bind): fix css v-bind in teleport in child compone…
Browse files Browse the repository at this point in the history
…nt slot
  • Loading branch information
yyx990803 committed Nov 10, 2022
1 parent 42239cf commit 11214ee
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 12 deletions.
17 changes: 7 additions & 10 deletions packages/runtime-core/src/components/Teleport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ export const TeleportImpl = {
}
}

updateCssVars(parentComponent, n2)
updateCssVars(n2)
},

remove(
Expand Down Expand Up @@ -385,7 +385,7 @@ function hydrateTeleport(
)
}
}
updateCssVars(parentComponent, vnode)
updateCssVars(vnode)
}
return vnode.anchor && nextSibling(vnode.anchor as Node)
}
Expand All @@ -396,19 +396,16 @@ export const Teleport = TeleportImpl as unknown as {
new (): { $props: VNodeProps & TeleportProps }
}

function updateCssVars(
parentComponent: ComponentInternalInstance | null,
vnode: VNode
) {
function updateCssVars(vnode: VNode) {
// presence of .ut method indicates owner component uses css vars.
// code path here can assume browser environment.
if (parentComponent && parentComponent.ut) {
const ctx = vnode.ctx
if (ctx && ctx.ut) {
let node = (vnode.children as VNode[])[0].el!
while (node !== vnode.targetAnchor) {
if (node.nodeType === 1)
node.setAttribute('data-v-owner', parentComponent.uid)
if (node.nodeType === 1) node.setAttribute('data-v-owner', ctx.uid)
node = node.nextSibling
}
parentComponent.ut()
ctx.ut()
}
}
11 changes: 9 additions & 2 deletions packages/runtime-core/src/vnode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,11 @@ export interface VNode<
// application root node only
appContext: AppContext | null

/**
* @internal lexical scope owner instance
*/
ctx: ComponentInternalInstance | null

/**
* @internal attached by v-memo
*/
Expand Down Expand Up @@ -439,7 +444,8 @@ function createBaseVNode(
patchFlag,
dynamicProps,
dynamicChildren: null,
appContext: null
appContext: null,
ctx: currentRenderingInstance
} as VNode

if (needFullChildrenNormalization) {
Expand Down Expand Up @@ -661,7 +667,8 @@ export function cloneVNode<T, U>(
ssContent: vnode.ssContent && cloneVNode(vnode.ssContent),
ssFallback: vnode.ssFallback && cloneVNode(vnode.ssFallback),
el: vnode.el,
anchor: vnode.anchor
anchor: vnode.anchor,
ctx: vnode.ctx
}
if (__COMPAT__) {
defineLegacyVNodeProperties(cloned as VNode)
Expand Down
24 changes: 24 additions & 0 deletions packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,30 @@ describe('useCssVars', () => {
}
})

test('with teleport in child slot', async () => {
document.body.innerHTML = ''
const state = reactive({ color: 'red' })
const root = document.createElement('div')
const target = document.body

const Child: FunctionalComponent = (_, { slots }) => {
return h('div', slots.default && slots.default())
}

const App = {
setup() {
useCssVars(() => state)
return () => h(Child, () => [h(Teleport, { to: target }, [h('div')])])
}
}

render(h(App), root)
await nextTick()
for (const c of [].slice.call(target.children as any)) {
expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('red')
}
})

test('with teleport(change subTree)', async () => {
document.body.innerHTML = ''
const state = reactive({ color: 'red' })
Expand Down

0 comments on commit 11214ee

Please sign in to comment.