diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts
index 1cde6442..9ae406e3 100644
--- a/packages/runtime-core/src/component.ts
+++ b/packages/runtime-core/src/component.ts
@@ -81,6 +81,7 @@ export interface FunctionalComponent<
props?: ComponentPropsOptions
emits?: E | (keyof E)[]
inheritAttrs?: boolean
+ inheritRef?: boolean
displayName?: string
}
diff --git a/packages/runtime-core/src/componentOptions.ts b/packages/runtime-core/src/componentOptions.ts
index 5ee630c4..206945fc 100644
--- a/packages/runtime-core/src/componentOptions.ts
+++ b/packages/runtime-core/src/componentOptions.ts
@@ -100,6 +100,7 @@ export interface ComponentOptionsBase<
components?: Record
directives?: Record
inheritAttrs?: boolean
+ inheritRef?: boolean
emits?: E | EE[]
// Internal ------------------------------------------------------------------
diff --git a/packages/runtime-core/src/componentRenderUtils.ts b/packages/runtime-core/src/componentRenderUtils.ts
index a83821b3..d63f804f 100644
--- a/packages/runtime-core/src/componentRenderUtils.ts
+++ b/packages/runtime-core/src/componentRenderUtils.ts
@@ -172,6 +172,10 @@ export function renderComponentRoot(
}
root.transition = vnode.transition
}
+ // inherit ref
+ if (Component.inheritRef && vnode.ref != null) {
+ root.ref = vnode.ref
+ }
if (__DEV__ && setRoot) {
setRoot(root)
diff --git a/packages/runtime-core/src/components/BaseTransition.ts b/packages/runtime-core/src/components/BaseTransition.ts
index 865432ab..1a92dffe 100644
--- a/packages/runtime-core/src/components/BaseTransition.ts
+++ b/packages/runtime-core/src/components/BaseTransition.ts
@@ -100,6 +100,8 @@ export function useTransitionState(): TransitionState {
const BaseTransitionImpl = {
name: `BaseTransition`,
+ inheritRef: true,
+
props: {
mode: String,
appear: Boolean,
diff --git a/packages/runtime-core/src/components/KeepAlive.ts b/packages/runtime-core/src/components/KeepAlive.ts
index 865cf8d2..ead43717 100644
--- a/packages/runtime-core/src/components/KeepAlive.ts
+++ b/packages/runtime-core/src/components/KeepAlive.ts
@@ -63,6 +63,8 @@ const KeepAliveImpl = {
// would prevent it from being tree-shaken.
__isKeepAlive: true,
+ inheritRef: true,
+
props: {
include: [String, RegExp, Array],
exclude: [String, RegExp, Array],
diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts
index f816459b..382cd379 100644
--- a/packages/runtime-core/src/renderer.ts
+++ b/packages/runtime-core/src/renderer.ts
@@ -17,7 +17,8 @@ import {
ComponentInternalInstance,
createComponentInstance,
Data,
- setupComponent
+ setupComponent,
+ Component
} from './component'
import {
renderComponentRoot,
@@ -64,6 +65,7 @@ import {
import { createHydrationFunctions, RootHydrateFunction } from './hydration'
import { invokeDirectiveHook } from './directives'
import { startMeasure, endMeasure } from './profiling'
+import { ComponentPublicInstance } from './componentProxy'
export interface Renderer {
render: RootRenderFunction
@@ -276,11 +278,21 @@ export const setRef = (
parent: ComponentInternalInstance,
vnode: VNode | null
) => {
- const value = vnode
- ? vnode.shapeFlag & ShapeFlags.STATEFUL_COMPONENT
- ? vnode.component!.proxy
- : vnode.el
- : null
+ let value: ComponentPublicInstance | RendererNode | null
+ if (!vnode) {
+ value = null
+ } else {
+ const { el, component, shapeFlag, type } = vnode
+ if (shapeFlag & ShapeFlags.COMPONENT && (type as Component).inheritRef) {
+ return
+ }
+ if (shapeFlag & ShapeFlags.STATEFUL_COMPONENT) {
+ value = component!.proxy
+ } else {
+ value = el
+ }
+ }
+
const [owner, ref] = rawRef
if (__DEV__ && !owner) {
warn(
diff --git a/packages/runtime-dom/src/components/Transition.ts b/packages/runtime-dom/src/components/Transition.ts
index 20e18f83..17fbf14e 100644
--- a/packages/runtime-dom/src/components/Transition.ts
+++ b/packages/runtime-dom/src/components/Transition.ts
@@ -37,6 +37,8 @@ export const Transition: FunctionalComponent = (
{ slots }
) => h(BaseTransition, resolveTransitionProps(props), slots)
+Transition.inheritRef = true
+
export const TransitionPropsValidators = (Transition.props = {
...(BaseTransition as any).props,
name: String,