فهرست منبع

fix(custom-element): ensure exposed methods are accessible from custom elements by making them enumerable (#13634)

close #13632
linzhe 9 ماه پیش
والد
کامیت
90573b06bf
2فایلهای تغییر یافته به همراه29 افزوده شده و 0 حذف شده
  1. 1 0
      packages/runtime-core/src/componentOptions.ts
  2. 28 0
      packages/runtime-dom/__tests__/customElement.spec.ts

+ 1 - 0
packages/runtime-core/src/componentOptions.ts

@@ -756,6 +756,7 @@ export function applyOptions(instance: ComponentInternalInstance): void {
         Object.defineProperty(exposed, key, {
           get: () => publicThis[key],
           set: val => (publicThis[key] = val),
+          enumerable: true,
         })
       })
     } else if (!instance.exposed) {

+ 28 - 0
packages/runtime-dom/__tests__/customElement.spec.ts

@@ -1402,6 +1402,34 @@ describe('defineCustomElement', () => {
   })
 
   describe('expose', () => {
+    test('expose w/ options api', async () => {
+      const E = defineCustomElement({
+        data() {
+          return {
+            value: 0,
+          }
+        },
+        methods: {
+          foo() {
+            ;(this as any).value++
+          },
+        },
+        expose: ['foo'],
+        render(_ctx: any) {
+          return h('div', null, _ctx.value)
+        },
+      })
+      customElements.define('my-el-expose-options-api', E)
+
+      container.innerHTML = `<my-el-expose-options-api></my-el-expose-options-api>`
+      const e = container.childNodes[0] as VueElement & {
+        foo: () => void
+      }
+      expect(e.shadowRoot!.innerHTML).toBe(`<div>0</div>`)
+      e.foo()
+      await nextTick()
+      expect(e.shadowRoot!.innerHTML).toBe(`<div>1</div>`)
+    })
     test('expose attributes and callback', async () => {
       type SetValue = (value: string) => void
       let fn: MockedFunction<SetValue>