} from '@vue/shared'
import { SuspenseBoundary } from './components/Suspense'
import { CompilerError, CompilerOptions } from '@vue/compiler-core'
+import { currentRenderingInstance } from './componentRenderUtils'
export type Data = { [key: string]: unknown }
sink: { [key: string]: any }
// lifecycle
+ isMounted: boolean
isUnmounted: boolean
isDeactivated: boolean
[LifecycleHooks.BEFORE_CREATE]: LifecycleHook
// lifecycle hooks
// not using enums here because it results in computed properties
+ isMounted: false,
isUnmounted: false,
isDeactivated: false,
bc: null,
export let currentSuspense: SuspenseBoundary | null = null
export const getCurrentInstance: () => ComponentInternalInstance | null = () =>
- currentInstance
+ currentInstance || currentRenderingInstance
export const setCurrentInstance = (
instance: ComponentInternalInstance | null
instance: ComponentInternalInstance,
setupRenderEffect: (
instance: ComponentInternalInstance,
- parentComponent: ComponentInternalInstance | null,
parentSuspense: SuspenseBoundary<HostNode, HostElement> | null,
initialVNode: VNode<HostNode, HostElement>,
container: HostElement,
handleSetupResult(instance, asyncSetupResult, suspense)
setupRenderEffect(
instance,
- parentComponent,
suspense,
vnode,
// component may have been moved before resolve
import { warn } from '../warning'
import { isKeepAlive } from './KeepAlive'
import { toRaw } from '@vue/reactivity'
-import { onMounted } from '../apiLifecycle'
import { callWithAsyncErrorHandling, ErrorCodes } from '../errorHandling'
import { ShapeFlags } from '../shapeFlags'
-// Using camel case here makes it easier to use in render functions & JSX.
-// In templates these will be written as @before-enter="xxx"
-// The compiler has special handling to convert them into the proper cases.
export interface TransitionProps {
mode?: 'in-out' | 'out-in' | 'default'
appear?: boolean
+
// If true, indicates this is a transition that doesn't actually insert/remove
// the element, but toggles the show / hidden status instead.
// The transition hooks are injected, but will be skipped by the renderer.
// Instead, a custom directive can control the transition by calling the
// injected hooks (e.g. v-show).
persisted?: boolean
+
+ // Hooks. Using camel casef for easier usage in render functions & JSX.
+ // In templates these will be written as @before-enter="xxx"
+ // The compiler has special handling to convert them into the proper cases.
// enter
onBeforeEnter?: (el: any) => void
onEnter?: (el: any, done: () => void) => void
name: `BaseTransition`,
setup(props: TransitionProps, { slots }: SetupContext) {
const instance = getCurrentInstance()!
- let isLeaving = false
- let isMounted = false
const pendingCallbacks: PendingCallbacks = {}
-
- onMounted(() => {
- isMounted = true
- })
+ let isLeaving = false
const callTransitionHook: TransitionHookCaller = (hook, args) => {
hook &&
const transitionHooks = (child.transition = resolveTransitionHooks(
rawProps,
callTransitionHook,
- isMounted,
+ instance.isMounted,
pendingCallbacks,
performDelayedLeave
))
setupRenderEffect(
instance,
- parentComponent,
parentSuspense,
initialVNode,
container,
function setupRenderEffect(
instance: ComponentInternalInstance,
- parentComponent: ComponentInternalInstance | null,
parentSuspense: HostSuspenseBoundary | null,
initialVNode: HostVNode,
container: HostElement,
isSVG: boolean
) {
// create reactive effect for rendering
- let mounted = false
instance.update = effect(function componentEffect() {
- if (!mounted) {
+ if (!instance.isMounted) {
const subTree = (instance.subTree = renderComponentRoot(instance))
// beforeMount hook
if (instance.bm !== null) {
) {
queuePostRenderEffect(instance.a, parentSuspense)
}
- mounted = true
+ instance.isMounted = true
} else {
// updateComponent
// This is triggered by mutation of component's own state (next: null)
TransitionProps,
h,
warn,
- FunctionalComponent
+ FunctionalComponent,
+ getCurrentInstance
} from '@vue/runtime-core'
import { isObject } from '@vue/shared'
-import { currentRenderingInstance } from 'packages/runtime-core/src/componentRenderUtils'
const TRANSITION = 'transition'
const ANIMATION = 'animation'
const { appear, onBeforeEnter, onEnter, onLeave } = baseProps
// is appearing
- if (appear && !currentRenderingInstance!.subTree) {
+ if (appear && !getCurrentInstance()!.isMounted) {
enterFromClass = appearFromClass
enterActiveClass = appearActiveClass
enterToClass = appearToClass