]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
chore: tweaks
authordaiwei <daiwei521@126.com>
Wed, 29 Oct 2025 08:56:28 +0000 (16:56 +0800)
committerdaiwei <daiwei521@126.com>
Wed, 29 Oct 2025 09:21:55 +0000 (17:21 +0800)
packages/runtime-dom/src/apiCustomElement.ts
packages/runtime-vapor/src/apiDefineVaporCustomElement.ts
packages/runtime-vapor/src/componentProps.ts
packages/vue/__tests__/e2e/ssr-custom-element-vapor.spec.ts [moved from packages/vue/__tests__/e2e/ssr-vapor-custom-element.spec.ts with 100% similarity]

index 40d21ec0be37dbffd272cb567161e1f3f645ade1..cf95eb4a805b625553099a21f33a6509bbe8c9c5 100644 (file)
@@ -220,7 +220,7 @@ export abstract class VueElementBase<
   /**
    * @internal
    */
-  _root!: Element | ShadowRoot
+  _root: Element | ShadowRoot
   /**
    * @internal
    */
@@ -230,9 +230,6 @@ export abstract class VueElementBase<
    */
   _teleportTargets?: Set<Element>
 
-  protected _def: Def
-  protected _props: Record<string, any>
-  protected _createApp: CreateAppFunction<E, C>
   protected _connected = false
   protected _resolved = false
   protected _numberProps: Record<string, true> | null = null
@@ -240,6 +237,10 @@ export abstract class VueElementBase<
   protected _pendingResolve: Promise<void> | undefined
   protected _parent: VueElementBase | undefined
 
+  protected _def: Def
+  protected _props: Record<string, any>
+  protected _createApp: CreateAppFunction<E, C>
+
   /**
    * dev only
    */
@@ -251,7 +252,12 @@ export abstract class VueElementBase<
   protected _ob?: MutationObserver | null = null
   protected _slots?: Record<string, Node[]>
 
-  protected abstract _hasPreRendered(): boolean | undefined
+  /**
+   * Check if this custom element needs hydration.
+   * Returns true if it has a pre-rendered declarative shadow root that
+   * needs to be hydrated.
+   */
+  protected abstract _needsHydration(): boolean
   protected abstract _mount(def: Def): void
   protected abstract _update(): void
   protected abstract _unmount(): void
@@ -272,7 +278,9 @@ export abstract class VueElementBase<
     this._createApp = createAppFn
     this._nonce = def.nonce
 
-    if (this._hasPreRendered()) {
+    if (this._needsHydration()) {
+      this._root = this.shadowRoot!
+    } else {
       if (def.shadowRoot !== false) {
         this.attachShadow(
           extend({}, def.shadowRootOptions, {
@@ -439,6 +447,7 @@ export abstract class VueElementBase<
 
   private _mountComponent(def: Def): void {
     this._mount(def)
+    // apply expose after mount
     this._processExposed()
   }
 
@@ -447,7 +456,9 @@ export abstract class VueElementBase<
     if (!exposed) return
     for (const key in exposed) {
       if (!hasOwn(this, key)) {
+        // exposed properties are readonly
         Object.defineProperty(this, key, {
+          // unwrap ref to be consistent with public instance behavior
           get: () => unref(exposed[key]),
         })
       } else if (__DEV__) {
@@ -723,9 +734,9 @@ export class VueElement extends VueElementBase<
     super(def, props, createAppFn)
   }
 
-  protected _hasPreRendered(): boolean | undefined {
+  protected _needsHydration(): boolean {
     if (this.shadowRoot && this._createApp !== createApp) {
-      this._root = this.shadowRoot
+      return true
     } else {
       if (__DEV__ && this.shadowRoot) {
         warn(
@@ -733,8 +744,8 @@ export class VueElement extends VueElementBase<
             `defined as hydratable. Use \`defineSSRCustomElement\`.`,
         )
       }
-      return true
     }
+    return false
   }
 
   protected _mount(def: InnerComponentDef): void {
index 7624b66cee1a097080d730955db1e11316fa77cf..f896b49eb5ba1217300867944b6fab26e55171fe 100644 (file)
@@ -70,9 +70,9 @@ export class VaporElement extends VueElementBase<
     super(def, props, createAppFn)
   }
 
-  protected _hasPreRendered(): boolean | undefined {
+  protected _needsHydration(): boolean {
     if (this.shadowRoot && this._createApp !== createVaporApp) {
-      this._root = this.shadowRoot
+      return true
     } else {
       if (__DEV__ && this.shadowRoot) {
         warn(
@@ -80,8 +80,8 @@ export class VaporElement extends VueElementBase<
             `defined as hydratable. Use \`defineVaporSSRCustomElement\`.`,
         )
       }
-      return true
     }
+    return false
   }
   protected _mount(def: VaporInnerComponentDef): void {
     if ((__DEV__ || __FEATURE_PROD_DEVTOOLS__) && !def.name) {
@@ -94,8 +94,8 @@ export class VaporElement extends VueElementBase<
       this._def.configureApp(this._app)
     }
 
-    // For SSR custom elements, we need to create component in hydration context
-    if (this._createApp === createVaporSSRApp) {
+    // create component in hydration context
+    if (this.shadowRoot && this._createApp === createVaporSSRApp) {
       withHydration(this._root, this._createComponent.bind(this))
     } else {
       this._createComponent()
index 496b001d3a26ea5de6199b5c5619dbcdcebff1e8..c10008b3af20f7d0b30569a8de6029cc78a5fb28 100644 (file)
@@ -97,7 +97,7 @@ export function getPropsProxyHandlers(
         return resolvePropValue(
           propsOptions!,
           key,
-          instance.type.ce ? rawProps[rawKey] : rawProps[rawKey](),
+          resolveSource(rawProps[rawKey]),
           instance,
           resolveDefault,
         )