mirror of https://github.com/vuejs/core.git
fix(ssr): make isInSSRComponentSetup state sharable across copies of Vue
This also fixes the issue when rendering async components in the SFC playground with SSR enabled.
This commit is contained in:
parent
b010fcfc5c
commit
e04d821422
|
@ -630,13 +630,10 @@ export let currentInstance: ComponentInternalInstance | null = null
|
|||
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
|
||||
|
@ -651,21 +648,36 @@ let settersKey = '__VUE_INSTANCE_SETTERS__'
|
|||
* 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) => {
|
||||
|
@ -699,7 +711,7 @@ export function setupComponent(
|
|||
instance: ComponentInternalInstance,
|
||||
isSSR = false
|
||||
) {
|
||||
isInSSRComponentSetup = isSSR
|
||||
isSSR && setInSSRSetupState(isSSR)
|
||||
|
||||
const { props, children } = instance.vnode
|
||||
const isStateful = isStatefulComponent(instance)
|
||||
|
@ -709,7 +721,8 @@ export function setupComponent(
|
|||
const setupResult = isStateful
|
||||
? setupStatefulComponent(instance, isSSR)
|
||||
: undefined
|
||||
isInSSRComponentSetup = false
|
||||
|
||||
isSSR && setInSSRSetupState(false)
|
||||
return setupResult
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue