|
|
@ -56,7 +56,8 @@ import { |
|
|
|
makeMap, |
|
|
|
isPromise, |
|
|
|
ShapeFlags, |
|
|
|
extend |
|
|
|
extend, |
|
|
|
getGlobalThis |
|
|
|
} from '@vue/shared' |
|
|
|
import { SuspenseBoundary } from './components/Suspense' |
|
|
|
import { CompilerOptions } from '@vue/compiler-core' |
|
|
@ -565,14 +566,73 @@ export let currentInstance: ComponentInternalInstance | null = null |
|
|
|
export const getCurrentInstance: () => ComponentInternalInstance | null = () => |
|
|
|
currentInstance || currentRenderingInstance |
|
|
|
|
|
|
|
type GlobalInstanceSetter = (( |
|
|
|
instance: ComponentInternalInstance | null |
|
|
|
) => void) & { version?: string } |
|
|
|
|
|
|
|
let globalCurrentInstanceSetters: GlobalInstanceSetter[] |
|
|
|
let internalSetCurrentInstance: GlobalInstanceSetter |
|
|
|
let hasWarnedDuplicatedVue = false |
|
|
|
|
|
|
|
/** |
|
|
|
* The following makes getCurrentInstance() usage across multiple copies of Vue |
|
|
|
* work. Some cases of how this can happen are summarized in #7590. In principle |
|
|
|
* the duplication should be avoided, but in practice there are often cases |
|
|
|
* where the user is unable to resolve on their own, especially in complicated |
|
|
|
* SSR setups. |
|
|
|
* |
|
|
|
* Note this fix is technically incomplete, as we still rely on other singletons |
|
|
|
* for effectScope and global reactive dependency maps. However, it does make |
|
|
|
* some of the most common cases work. It also warns if the duplication is |
|
|
|
* found during browser execution. |
|
|
|
*/ |
|
|
|
if (__SSR__) { |
|
|
|
const settersKey = '__VUE_INSTANCE_SETTERS__' |
|
|
|
if (!(globalCurrentInstanceSetters = getGlobalThis()[settersKey])) { |
|
|
|
globalCurrentInstanceSetters = getGlobalThis()[settersKey] = [] |
|
|
|
} |
|
|
|
globalCurrentInstanceSetters.push(i => (currentInstance = i)) |
|
|
|
|
|
|
|
if (__DEV__) { |
|
|
|
globalCurrentInstanceSetters[ |
|
|
|
globalCurrentInstanceSetters.length - 1 |
|
|
|
].version = __VERSION__ |
|
|
|
} |
|
|
|
|
|
|
|
internalSetCurrentInstance = instance => { |
|
|
|
if (globalCurrentInstanceSetters.length > 1) { |
|
|
|
// eslint-disable-next-line no-restricted-globals
|
|
|
|
if (__DEV__ && !hasWarnedDuplicatedVue && typeof window !== 'undefined') { |
|
|
|
warn( |
|
|
|
`Mixed usage of duplicated Vue runtimes detected: ${globalCurrentInstanceSetters |
|
|
|
.map(fn => fn.version) |
|
|
|
.join(', ')}.\n` +
|
|
|
|
`This likely means there are multiple versions of Vue ` + |
|
|
|
`duplicated in your dependency tree, and could lead to errors. ` + |
|
|
|
`To avoid this warning, ensure that the all imports of Vue are resolving to ` + |
|
|
|
`the same location on disk.` |
|
|
|
) |
|
|
|
hasWarnedDuplicatedVue = true |
|
|
|
} |
|
|
|
globalCurrentInstanceSetters.forEach(s => s(instance)) |
|
|
|
} else { |
|
|
|
globalCurrentInstanceSetters[0](instance) |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
internalSetCurrentInstance = i => { |
|
|
|
currentInstance = i |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
export const setCurrentInstance = (instance: ComponentInternalInstance) => { |
|
|
|
currentInstance = instance |
|
|
|
internalSetCurrentInstance(instance) |
|
|
|
instance.scope.on() |
|
|
|
} |
|
|
|
|
|
|
|
export const unsetCurrentInstance = () => { |
|
|
|
currentInstance && currentInstance.scope.off() |
|
|
|
currentInstance = null |
|
|
|
internalSetCurrentInstance(null) |
|
|
|
} |
|
|
|
|
|
|
|
const isBuiltInTag = /*#__PURE__*/ makeMap('slot,component') |
|
|
|