Skip to content

Commit 415091b

Browse files
committed
fix(compiler-core): should generate HYDRATE_EVENTS flag on dynamic component that resolves to element
fix #5870
1 parent f811dc2 commit 415091b

File tree

5 files changed

+45
-6
lines changed

5 files changed

+45
-6
lines changed

packages/compiler-core/__tests__/transforms/transformElement.spec.ts

+15
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,21 @@ describe('compiler: element transform', () => {
10531053
genFlagText([PatchFlags.PROPS, PatchFlags.HYDRATE_EVENTS])
10541054
)
10551055
})
1056+
1057+
// #5870
1058+
test('HYDRATE_EVENTS on dynamic component', () => {
1059+
const { node } = parseWithElementTransform(
1060+
`<component :is="foo" @input="foo" />`,
1061+
{
1062+
directiveTransforms: {
1063+
on: transformOn
1064+
}
1065+
}
1066+
)
1067+
expect(node.patchFlag).toBe(
1068+
genFlagText([PatchFlags.PROPS, PatchFlags.HYDRATE_EVENTS])
1069+
)
1070+
})
10561071
})
10571072

10581073
describe('dynamic component', () => {

packages/compiler-core/src/transforms/transformElement.ts

+10-3
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,13 @@ export const transformElement: NodeTransform = (node, context) => {
121121

122122
// props
123123
if (props.length > 0) {
124-
const propsBuildResult = buildProps(node, context)
124+
const propsBuildResult = buildProps(
125+
node,
126+
context,
127+
undefined,
128+
isComponent,
129+
isDynamicComponent
130+
)
125131
vnodeProps = propsBuildResult.props
126132
patchFlag = propsBuildResult.patchFlag
127133
dynamicPropNames = propsBuildResult.dynamicPropNames
@@ -380,6 +386,8 @@ export function buildProps(
380386
node: ElementNode,
381387
context: TransformContext,
382388
props: ElementNode['props'] = node.props,
389+
isComponent: boolean,
390+
isDynamicComponent: boolean,
383391
ssr = false
384392
): {
385393
props: PropsExpression | undefined
@@ -389,7 +397,6 @@ export function buildProps(
389397
shouldUseBlock: boolean
390398
} {
391399
const { tag, loc: elementLoc, children } = node
392-
const isComponent = node.tagType === ElementTypes.COMPONENT
393400
let properties: ObjectExpression['properties'] = []
394401
const mergeArgs: PropsExpression[] = []
395402
const runtimeDirectives: DirectiveNode[] = []
@@ -411,8 +418,8 @@ export function buildProps(
411418
const name = key.content
412419
const isEventHandler = isOn(name)
413420
if (
414-
!isComponent &&
415421
isEventHandler &&
422+
(!isComponent || isDynamicComponent) &&
416423
// omit the flag for click handlers because hydration gives click
417424
// dedicated fast path.
418425
name.toLowerCase() !== 'onclick' &&

packages/compiler-core/src/transforms/transformSlotOutlet.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,13 @@ export function processSlotOutlet(
8787
}
8888

8989
if (nonNameProps.length > 0) {
90-
const { props, directives } = buildProps(node, context, nonNameProps)
90+
const { props, directives } = buildProps(
91+
node,
92+
context,
93+
nonNameProps,
94+
false,
95+
false
96+
)
9197
slotProps = props
9298

9399
if (directives.length) {

packages/compiler-ssr/src/transforms/ssrTransformComponent.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ import {
3434
TRANSITION_GROUP,
3535
CREATE_VNODE,
3636
CallExpression,
37-
JSChildNode
37+
JSChildNode,
38+
RESOLVE_DYNAMIC_COMPONENT
3839
} from '@vue/compiler-dom'
3940
import { SSR_RENDER_COMPONENT, SSR_RENDER_VNODE } from '../runtimeHelpers'
4041
import {
@@ -83,6 +84,8 @@ export const ssrTransformComponent: NodeTransform = (node, context) => {
8384
}
8485

8586
const component = resolveComponentType(node, context, true /* ssr */)
87+
const isDynamicComponent =
88+
isObject(component) && component.callee === RESOLVE_DYNAMIC_COMPONENT
8689
componentTypeMap.set(node, component)
8790

8891
if (isSymbol(component)) {
@@ -116,7 +119,13 @@ export const ssrTransformComponent: NodeTransform = (node, context) => {
116119
if (node.props.length) {
117120
// note we are not passing ssr: true here because for components, v-on
118121
// handlers should still be passed
119-
const { props, directives } = buildProps(node, context)
122+
const { props, directives } = buildProps(
123+
node,
124+
context,
125+
undefined,
126+
true,
127+
isDynamicComponent
128+
)
120129
if (props || directives.length) {
121130
propsExp = buildSSRProps(props, directives, context)
122131
}

packages/compiler-ssr/src/transforms/ssrTransformElement.ts

+2
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ export const ssrTransformElement: NodeTransform = (node, context) => {
8989
node,
9090
context,
9191
node.props,
92+
false /* isComponent */,
93+
false /* isDynamicComponent */,
9294
true /* ssr */
9395
)
9496
if (props || directives.length) {

0 commit comments

Comments
 (0)