Async custom element does not inject value if it was moved before it was loaded
Vue version
3.2.47
Link to minimal reproduction
https://stackblitz.com/edit/vite-m1kzad?file=main.js
Steps to reproduce
- Open the page
- Wait for async component to resolve
- Validate that it renders
provided value
- Uncomment
setTimeout
- Validate that it renders
default value
What is expected?
Both times provided value
should be rendered
What is actually happening?
default value
is rendered second time instead
System Info
No response
Any additional comments?
I was reading the source code for apiCustomElement.ts
to better understand how provide/inject works in custom elements.
I've noticed that in _resolveDef
method property _resolved
is assigned to true
before it is actually resolved. Since that property is queried in connectedCallback
, I've wondered if I can move element before it is actually resolved, and that if that would force resolve
method to run immediately. Sure enough it did.
However, this did not break rendering of the element, so it seems that render function handles different types of vnodes correctly (vnode.type
returns different values, which probably also shouldn't be the case). But since internal Vue instance is created before definition was loaded, it does not know what values to provide
Maybe something like this will work? Sorry, haven't tested this yet, just an idea.
apiCustomElement.ts
export class VueElement extends BaseClass {
private _loading = false
...
private _resolveDef() {
if (this._loading) {
return
}
this._loading = true
...
const resolve = (def: InnerComponentDef, isAsync = false) => {
this._resolved = true
this._loading = false
const { props, styles } = def
...
}
...
}
}