]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(custom-element): useHost() helper
authorEvan You <evan@vuejs.org>
Thu, 8 Aug 2024 04:35:00 +0000 (12:35 +0800)
committerEvan You <evan@vuejs.org>
Thu, 8 Aug 2024 04:35:00 +0000 (12:35 +0800)
packages/runtime-dom/__tests__/customElement.spec.ts
packages/runtime-dom/src/apiCustomElement.ts
packages/runtime-dom/src/index.ts

index c77828b66a3bba119c75acf59260aaf3b1942ff9..eb7a4b368d7261c29b8afca514bdbc9e8b05cb82 100644 (file)
@@ -14,6 +14,7 @@ import {
   ref,
   render,
   renderSlot,
+  useHost,
   useShadowRoot,
 } from '../src'
 
@@ -975,8 +976,22 @@ describe('defineCustomElement', () => {
     })
   })
 
-  describe('useShadowRoot', () => {
-    test('should work for style injection', () => {
+  describe('helpers', () => {
+    test('useHost', () => {
+      const Foo = defineCustomElement({
+        setup() {
+          const host = useHost()!
+          host.setAttribute('id', 'host')
+          return () => h('div', 'hello')
+        },
+      })
+      customElements.define('my-el-use-host', Foo)
+      container.innerHTML = `<my-el-use-host>`
+      const el = container.childNodes[0] as VueElement
+      expect(el.id).toBe('host')
+    })
+
+    test('useShadowRoot for style injection', () => {
       const Foo = defineCustomElement({
         setup() {
           const root = useShadowRoot()!
@@ -986,8 +1001,8 @@ describe('defineCustomElement', () => {
           return () => h('div', 'hello')
         },
       })
-      customElements.define('my-el', Foo)
-      container.innerHTML = `<my-el></my-el>`
+      customElements.define('my-el-use-shadow-root', Foo)
+      container.innerHTML = `<my-el-use-shadow-root>`
       const el = container.childNodes[0] as VueElement
       const style = el.shadowRoot?.querySelector('style')!
       expect(style.textContent).toBe(`div { color: red; }`)
index 694f9e0c7e374c18a88134aa48960d40cb8894af..af6063cdb02262a831d50977d747cf64782aaa03 100644 (file)
@@ -653,24 +653,31 @@ export class VueElement
   }
 }
 
-/**
- * Retrieve the shadowRoot of the current custom element. Only usable in setup()
- * of a `defineCustomElement` component.
- */
-export function useShadowRoot(): ShadowRoot | null {
+export function useHost(caller?: string): VueElement | null {
   const instance = getCurrentInstance()
-  const el = instance && instance.ce
+  const el = instance && (instance.ce as VueElement)
   if (el) {
-    return (el as VueElement).shadowRoot
+    return el
   } else if (__DEV__) {
     if (!instance) {
-      warn(`useShadowRoot called without an active component instance.`)
+      warn(
+        `${caller || 'useHost'} called without an active component instance.`,
+      )
     } else {
       warn(
-        `useShadowRoot can only be used in components defined via ` +
+        `${caller || 'useHost'} can only be used in components defined via ` +
           `defineCustomElement.`,
       )
     }
   }
   return null
 }
+
+/**
+ * Retrieve the shadowRoot of the current custom element. Only usable in setup()
+ * of a `defineCustomElement` component.
+ */
+export function useShadowRoot(): ShadowRoot | null {
+  const el = __DEV__ ? useHost('useShadowRoot') : useHost()
+  return el && el.shadowRoot
+}
index 706401ddd89c13b4751d53238e9543007c9d4b7d..95f27353a72c4ac6ebe7a0ed0611c06d268692d3 100644 (file)
@@ -247,6 +247,7 @@ export {
   defineCustomElement,
   defineSSRCustomElement,
   useShadowRoot,
+  useHost,
   VueElement,
   type VueElementConstructor,
   type CustomElementOptions,