export const getCurrentInstance: () => ComponentInternalInstance | null = () =>
currentInstance || currentRenderingInstance
-type GlobalInstanceSetter = ((
+let internalSetCurrentInstance: (
instance: ComponentInternalInstance | null
-) => void) & { version?: string }
-
-let internalSetCurrentInstance: GlobalInstanceSetter
-let globalCurrentInstanceSetters: GlobalInstanceSetter[]
-let settersKey = '__VUE_INSTANCE_SETTERS__'
+) => void
+let setInSSRSetupState: (state: boolean) => void
/**
* The following makes getCurrentInstance() usage across multiple copies of Vue
* found during browser execution.
*/
if (__SSR__) {
- if (!(globalCurrentInstanceSetters = getGlobalThis()[settersKey])) {
- globalCurrentInstanceSetters = getGlobalThis()[settersKey] = []
- }
- globalCurrentInstanceSetters.push(i => (currentInstance = i))
- internalSetCurrentInstance = instance => {
- if (globalCurrentInstanceSetters.length > 1) {
- globalCurrentInstanceSetters.forEach(s => s(instance))
- } else {
- globalCurrentInstanceSetters[0](instance)
+ type Setter = (v: any) => void
+ const g = getGlobalThis()
+ const registerGlobalSetter = (key: string, setter: Setter) => {
+ let setters: Setter[]
+ if (!(setters = g[key])) setters = g[key] = []
+ setters.push(setter)
+ return (v: any) => {
+ if (setters.length > 1) setters.forEach(set => set(v))
+ else setters[0](v)
}
}
+ internalSetCurrentInstance = registerGlobalSetter(
+ `__VUE_INSTANCE_SETTERS__`,
+ v => (currentInstance = v)
+ )
+ // also make `isInSSRComponentSetup` sharable across copies of Vue.
+ // this is needed in the SFC playground when SSRing async components, since
+ // we have to load both the runtime and the server-renderer from CDNs, they
+ // contain duplicated copies of Vue runtime code.
+ setInSSRSetupState = registerGlobalSetter(
+ `__VUE_SSR_SETTERS__`,
+ v => (isInSSRComponentSetup = v)
+ )
} else {
internalSetCurrentInstance = i => {
currentInstance = i
}
+ setInSSRSetupState = v => {
+ isInSSRComponentSetup = v
+ }
}
export const setCurrentInstance = (instance: ComponentInternalInstance) => {
instance: ComponentInternalInstance,
isSSR = false
) {
- isInSSRComponentSetup = isSSR
+ isSSR && setInSSRSetupState(isSSR)
const { props, children } = instance.vnode
const isStateful = isStatefulComponent(instance)
const setupResult = isStateful
? setupStatefulComponent(instance, isSSR)
: undefined
- isInSSRComponentSetup = false
+
+ isSSR && setInSSRSetupState(false)
return setupResult
}