Skip to content

Commit

Permalink
fix(custom-element): support early-set domProps for async custom elem…
Browse files Browse the repository at this point in the history
…ents

close #11081
close #11082
  • Loading branch information
yyx990803 committed Aug 8, 2024
1 parent 9b531d5 commit a07e7bf
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 5 deletions.
35 changes: 35 additions & 0 deletions packages/runtime-dom/__tests__/customElement.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1206,4 +1206,39 @@ describe('defineCustomElement', () => {
'hello',
)
})

// #11081
test('Props can be casted when mounting custom elements in component rendering functions', async () => {
const E = defineCustomElement(
defineAsyncComponent(() =>
Promise.resolve({
props: ['fooValue'],
setup(props) {
expect(props.fooValue).toBe('fooValue')
return () => h('div', props.fooValue)
},
}),
),
)
customElements.define('my-el-async-4', E)
const R = defineComponent({
setup() {
const fooValue = ref('fooValue')
return () => {
return h('div', null, [
h('my-el-async-4', {
fooValue: fooValue.value,
}),
])
}
},
})

const app = createApp(R)
app.mount(container)
await new Promise(r => setTimeout(r))
const e = container.querySelector('my-el-async-4') as VueElement
expect(e.shadowRoot!.innerHTML).toBe(`<div>fooValue</div>`)
app.unmount()
})
})
9 changes: 5 additions & 4 deletions packages/runtime-dom/src/apiCustomElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ export class VueElement
extends BaseClass
implements ComponentCustomElementInterface
{
_isVueCE = true
/**
* @internal
*/
Expand All @@ -208,6 +209,10 @@ export class VueElement
* @internal
*/
_app: App | null = null
/**
* @internal
*/
_root: Element | ShadowRoot
/**
* @internal
*/
Expand All @@ -228,10 +233,6 @@ export class VueElement
*/
private _childStyles?: Map<string, HTMLStyleElement[]>
private _ob?: MutationObserver | null = null
/**
* @internal
*/
public _root: Element | ShadowRoot
private _slots?: Record<string, Node[]>

constructor(
Expand Down
12 changes: 11 additions & 1 deletion packages/runtime-dom/src/patchProp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { patchDOMProp } from './modules/props'
import { patchEvent } from './modules/events'
import { isFunction, isModelListener, isOn, isString } from '@vue/shared'
import type { RendererOptions } from '@vue/runtime-core'
import type { VueElement } from './apiCustomElement'

const isNativeOn = (key: string) =>
key.charCodeAt(0) === 111 /* o */ &&
Expand Down Expand Up @@ -127,5 +128,14 @@ function shouldSetAsProp(
return false
}

return key in el
if (key in el) {
return true
}

// #11081 force set props for possible async custom element
if ((el as VueElement)._isVueCE && (/[A-Z]/.test(key) || !isString(value))) {
return true
}

return false
}

0 comments on commit a07e7bf

Please sign in to comment.