Skip to content

Commit 6f6ab1a

Browse files
authored
fix(runtime-vapor): dynamic component attrs fallthrough (#13466)
1 parent d65675d commit 6f6ab1a

File tree

3 files changed

+65
-9
lines changed

3 files changed

+65
-9
lines changed

packages/runtime-vapor/__tests__/componentAttrs.spec.ts

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import {
88
} from '@vue/runtime-dom'
99
import {
1010
createComponent,
11+
createDynamicComponent,
12+
createSlot,
1113
defineVaporComponent,
1214
renderEffect,
1315
setClass,
@@ -285,7 +287,43 @@ describe('attribute fallthrough', () => {
285287
expect(getCSS()).not.toContain('font-size:bold')
286288
})
287289

288-
test('parent value should take priority', async () => {
290+
it('should fallthrough attrs to dynamic component', async () => {
291+
const Comp = defineVaporComponent({
292+
setup() {
293+
const n1 = createDynamicComponent(
294+
() => 'button',
295+
null,
296+
{
297+
default: () => {
298+
const n0 = createSlot('default', null)
299+
return n0
300+
},
301+
},
302+
true,
303+
)
304+
return n1
305+
},
306+
})
307+
308+
const { html } = define({
309+
setup() {
310+
return createComponent(
311+
Comp,
312+
{
313+
class: () => 'foo',
314+
},
315+
null,
316+
true,
317+
)
318+
},
319+
}).render()
320+
321+
expect(html()).toBe(
322+
'<button class="foo"><!--slot--></button><!--dynamic-component-->',
323+
)
324+
})
325+
326+
it('parent value should take priority', async () => {
289327
const parentVal = ref('parent')
290328
const childVal = ref('child')
291329

packages/runtime-vapor/src/component.ts

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
unregisterHMR,
2626
warn,
2727
} from '@vue/runtime-dom'
28-
import { type Block, insert, isBlock, remove } from './block'
28+
import { type Block, DynamicFragment, insert, isBlock, remove } from './block'
2929
import {
3030
type ShallowRef,
3131
markRaw,
@@ -255,14 +255,16 @@ export function createComponent(
255255
if (
256256
instance.hasFallthrough &&
257257
component.inheritAttrs !== false &&
258-
instance.block instanceof Element &&
259258
Object.keys(instance.attrs).length
260259
) {
261-
renderEffect(() => {
262-
isApplyingFallthroughProps = true
263-
setDynamicProps(instance.block as Element, [instance.attrs])
264-
isApplyingFallthroughProps = false
265-
})
260+
const el = getRootElement(instance)
261+
if (el) {
262+
renderEffect(() => {
263+
isApplyingFallthroughProps = true
264+
setDynamicProps(el, [instance.attrs])
265+
isApplyingFallthroughProps = false
266+
})
267+
}
266268
}
267269

268270
resetTracking()
@@ -563,3 +565,18 @@ export function getExposed(
563565
)
564566
}
565567
}
568+
569+
function getRootElement({
570+
block,
571+
}: VaporComponentInstance): Element | undefined {
572+
if (block instanceof Element) {
573+
return block
574+
}
575+
576+
if (block instanceof DynamicFragment) {
577+
const { nodes } = block
578+
if (nodes instanceof Element && (nodes as any).$root) {
579+
return nodes
580+
}
581+
}
582+
}

packages/runtime-vapor/src/componentProps.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,8 @@ export function hasAttrFromRawProps(rawProps: RawProps, key: string): boolean {
210210
if (dynamicSources) {
211211
let i = dynamicSources.length
212212
while (i--) {
213-
if (hasOwn(resolveSource(dynamicSources[i]), key)) {
213+
const source = resolveSource(dynamicSources[i])
214+
if (source && hasOwn(source, key)) {
214215
return true
215216
}
216217
}

0 commit comments

Comments
 (0)