Skip to content

Commit 90573b0

Browse files
authored
fix(custom-element): ensure exposed methods are accessible from custom elements by making them enumerable (#13634)
close #13632
1 parent c5f7db1 commit 90573b0

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

packages/runtime-core/src/componentOptions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,7 @@ export function applyOptions(instance: ComponentInternalInstance): void {
756756
Object.defineProperty(exposed, key, {
757757
get: () => publicThis[key],
758758
set: val => (publicThis[key] = val),
759+
enumerable: true,
759760
})
760761
})
761762
} else if (!instance.exposed) {

packages/runtime-dom/__tests__/customElement.spec.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,6 +1402,34 @@ describe('defineCustomElement', () => {
14021402
})
14031403

14041404
describe('expose', () => {
1405+
test('expose w/ options api', async () => {
1406+
const E = defineCustomElement({
1407+
data() {
1408+
return {
1409+
value: 0,
1410+
}
1411+
},
1412+
methods: {
1413+
foo() {
1414+
;(this as any).value++
1415+
},
1416+
},
1417+
expose: ['foo'],
1418+
render(_ctx: any) {
1419+
return h('div', null, _ctx.value)
1420+
},
1421+
})
1422+
customElements.define('my-el-expose-options-api', E)
1423+
1424+
container.innerHTML = `<my-el-expose-options-api></my-el-expose-options-api>`
1425+
const e = container.childNodes[0] as VueElement & {
1426+
foo: () => void
1427+
}
1428+
expect(e.shadowRoot!.innerHTML).toBe(`<div>0</div>`)
1429+
e.foo()
1430+
await nextTick()
1431+
expect(e.shadowRoot!.innerHTML).toBe(`<div>1</div>`)
1432+
})
14051433
test('expose attributes and callback', async () => {
14061434
type SetValue = (value: string) => void
14071435
let fn: MockedFunction<SetValue>

0 commit comments

Comments
 (0)