]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-core): should generate HYDRATE_EVENTS flag on dynamic component that...
authorEvan You <yyx990803@gmail.com>
Tue, 17 May 2022 08:39:48 +0000 (16:39 +0800)
committerEvan You <yyx990803@gmail.com>
Tue, 17 May 2022 08:39:48 +0000 (16:39 +0800)
fix #5870

packages/compiler-core/__tests__/transforms/transformElement.spec.ts
packages/compiler-core/src/transforms/transformElement.ts
packages/compiler-core/src/transforms/transformSlotOutlet.ts
packages/compiler-ssr/src/transforms/ssrTransformComponent.ts
packages/compiler-ssr/src/transforms/ssrTransformElement.ts

index b672799adf4a0ce89fd8b071ba108cbfee2a7d4f..bec7e119bd3d8209b5ff00ab9a0985eaab8d5e9c 100644 (file)
@@ -1053,6 +1053,21 @@ describe('compiler: element transform', () => {
         genFlagText([PatchFlags.PROPS, PatchFlags.HYDRATE_EVENTS])
       )
     })
+
+    // #5870
+    test('HYDRATE_EVENTS on dynamic component', () => {
+      const { node } = parseWithElementTransform(
+        `<component :is="foo" @input="foo" />`,
+        {
+          directiveTransforms: {
+            on: transformOn
+          }
+        }
+      )
+      expect(node.patchFlag).toBe(
+        genFlagText([PatchFlags.PROPS, PatchFlags.HYDRATE_EVENTS])
+      )
+    })
   })
 
   describe('dynamic component', () => {
index 403c5c6e382f7231624fab64651c4e9d190e6e62..2d15227f70f6e038d85660fc6155b13b44e09a80 100644 (file)
@@ -121,7 +121,13 @@ export const transformElement: NodeTransform = (node, context) => {
 
     // props
     if (props.length > 0) {
-      const propsBuildResult = buildProps(node, context)
+      const propsBuildResult = buildProps(
+        node,
+        context,
+        undefined,
+        isComponent,
+        isDynamicComponent
+      )
       vnodeProps = propsBuildResult.props
       patchFlag = propsBuildResult.patchFlag
       dynamicPropNames = propsBuildResult.dynamicPropNames
@@ -380,6 +386,8 @@ export function buildProps(
   node: ElementNode,
   context: TransformContext,
   props: ElementNode['props'] = node.props,
+  isComponent: boolean,
+  isDynamicComponent: boolean,
   ssr = false
 ): {
   props: PropsExpression | undefined
@@ -389,7 +397,6 @@ export function buildProps(
   shouldUseBlock: boolean
 } {
   const { tag, loc: elementLoc, children } = node
-  const isComponent = node.tagType === ElementTypes.COMPONENT
   let properties: ObjectExpression['properties'] = []
   const mergeArgs: PropsExpression[] = []
   const runtimeDirectives: DirectiveNode[] = []
@@ -411,8 +418,8 @@ export function buildProps(
       const name = key.content
       const isEventHandler = isOn(name)
       if (
-        !isComponent &&
         isEventHandler &&
+        (!isComponent || isDynamicComponent) &&
         // omit the flag for click handlers because hydration gives click
         // dedicated fast path.
         name.toLowerCase() !== 'onclick' &&
index 394684b408d96c7064cdee22d793b94882920302..409bfabb6edaa4462cb09197f35562daf21359a8 100644 (file)
@@ -87,7 +87,13 @@ export function processSlotOutlet(
   }
 
   if (nonNameProps.length > 0) {
-    const { props, directives } = buildProps(node, context, nonNameProps)
+    const { props, directives } = buildProps(
+      node,
+      context,
+      nonNameProps,
+      false,
+      false
+    )
     slotProps = props
 
     if (directives.length) {
index b02d3afddb5aaed972846c30258068db56458a6a..dfb78136a9ddcb6f107af0f803933233af85425b 100644 (file)
@@ -34,7 +34,8 @@ import {
   TRANSITION_GROUP,
   CREATE_VNODE,
   CallExpression,
-  JSChildNode
+  JSChildNode,
+  RESOLVE_DYNAMIC_COMPONENT
 } from '@vue/compiler-dom'
 import { SSR_RENDER_COMPONENT, SSR_RENDER_VNODE } from '../runtimeHelpers'
 import {
@@ -83,6 +84,8 @@ export const ssrTransformComponent: NodeTransform = (node, context) => {
   }
 
   const component = resolveComponentType(node, context, true /* ssr */)
+  const isDynamicComponent =
+    isObject(component) && component.callee === RESOLVE_DYNAMIC_COMPONENT
   componentTypeMap.set(node, component)
 
   if (isSymbol(component)) {
@@ -116,7 +119,13 @@ export const ssrTransformComponent: NodeTransform = (node, context) => {
     if (node.props.length) {
       // note we are not passing ssr: true here because for components, v-on
       // handlers should still be passed
-      const { props, directives } = buildProps(node, context)
+      const { props, directives } = buildProps(
+        node,
+        context,
+        undefined,
+        true,
+        isDynamicComponent
+      )
       if (props || directives.length) {
         propsExp = buildSSRProps(props, directives, context)
       }
index be530ebb5bc6f925d44687397cc4ead9f1575c40..a082d94eb575f3e308a0cb5923bf9706906258f0 100644 (file)
@@ -89,6 +89,8 @@ export const ssrTransformElement: NodeTransform = (node, context) => {
         node,
         context,
         node.props,
+        false /* isComponent */,
+        false /* isDynamicComponent */,
         true /* ssr */
       )
       if (props || directives.length) {