mirror of https://github.com/vuejs/core.git
fix(runtime-vapor): dynamic component attrs fallthrough
This commit is contained in:
parent
1ef6e6edb7
commit
a93b49ce97
|
@ -1,6 +1,8 @@
|
||||||
import { type Ref, nextTick, ref } from '@vue/runtime-dom'
|
import { type Ref, nextTick, ref } from '@vue/runtime-dom'
|
||||||
import {
|
import {
|
||||||
createComponent,
|
createComponent,
|
||||||
|
createDynamicComponent,
|
||||||
|
createSlot,
|
||||||
defineVaporComponent,
|
defineVaporComponent,
|
||||||
renderEffect,
|
renderEffect,
|
||||||
setClass,
|
setClass,
|
||||||
|
@ -277,7 +279,43 @@ describe('attribute fallthrough', () => {
|
||||||
expect(getCSS()).not.toContain('font-size:bold')
|
expect(getCSS()).not.toContain('font-size:bold')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('parent value should take priority', async () => {
|
it('should fallthrough attrs to dynamic component', async () => {
|
||||||
|
const Comp = defineVaporComponent({
|
||||||
|
setup() {
|
||||||
|
const n1 = createDynamicComponent(
|
||||||
|
() => 'button',
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
default: () => {
|
||||||
|
const n0 = createSlot('default', null)
|
||||||
|
return n0
|
||||||
|
},
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
return n1
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const { html } = define({
|
||||||
|
setup() {
|
||||||
|
return createComponent(
|
||||||
|
Comp,
|
||||||
|
{
|
||||||
|
class: () => 'foo',
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
}).render()
|
||||||
|
|
||||||
|
expect(html()).toBe(
|
||||||
|
'<button class="foo"><!--slot--></button><!--dynamic-component-->',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('parent value should take priority', async () => {
|
||||||
const parentVal = ref('parent')
|
const parentVal = ref('parent')
|
||||||
const childVal = ref('child')
|
const childVal = ref('child')
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ import {
|
||||||
unregisterHMR,
|
unregisterHMR,
|
||||||
warn,
|
warn,
|
||||||
} from '@vue/runtime-dom'
|
} from '@vue/runtime-dom'
|
||||||
import { type Block, insert, isBlock, remove } from './block'
|
import { type Block, DynamicFragment, insert, isBlock, remove } from './block'
|
||||||
import {
|
import {
|
||||||
type ShallowRef,
|
type ShallowRef,
|
||||||
markRaw,
|
markRaw,
|
||||||
|
@ -249,14 +249,16 @@ export function createComponent(
|
||||||
if (
|
if (
|
||||||
instance.hasFallthrough &&
|
instance.hasFallthrough &&
|
||||||
component.inheritAttrs !== false &&
|
component.inheritAttrs !== false &&
|
||||||
instance.block instanceof Element &&
|
|
||||||
Object.keys(instance.attrs).length
|
Object.keys(instance.attrs).length
|
||||||
) {
|
) {
|
||||||
renderEffect(() => {
|
const el = getRootElement(instance)
|
||||||
isApplyingFallthroughProps = true
|
if (el) {
|
||||||
setDynamicProps(instance.block as Element, [instance.attrs])
|
renderEffect(() => {
|
||||||
isApplyingFallthroughProps = false
|
isApplyingFallthroughProps = true
|
||||||
})
|
setDynamicProps(el, [instance.attrs])
|
||||||
|
isApplyingFallthroughProps = false
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resetTracking()
|
resetTracking()
|
||||||
|
@ -545,3 +547,18 @@ export function getExposed(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getRootElement({
|
||||||
|
block,
|
||||||
|
}: VaporComponentInstance): Element | undefined {
|
||||||
|
if (block instanceof Element) {
|
||||||
|
return block
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block instanceof DynamicFragment) {
|
||||||
|
const { nodes } = block
|
||||||
|
if (nodes instanceof Element && (nodes as any).$root) {
|
||||||
|
return nodes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -210,7 +210,8 @@ export function hasAttrFromRawProps(rawProps: RawProps, key: string): boolean {
|
||||||
if (dynamicSources) {
|
if (dynamicSources) {
|
||||||
let i = dynamicSources.length
|
let i = dynamicSources.length
|
||||||
while (i--) {
|
while (i--) {
|
||||||
if (hasOwn(resolveSource(dynamicSources[i]), key)) {
|
const source = resolveSource(dynamicSources[i])
|
||||||
|
if (source && hasOwn(source, key)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue