From 5b76843b693d6477ae44b4bd238c2c892d8f4c77 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 22 Jul 2021 18:19:54 -0400 Subject: [PATCH] feat(runtime-dom): support passing initial props to custom element constructor --- .../runtime-dom/__tests__/customElement.spec.ts | 14 +++++++++++--- packages/runtime-dom/src/apiCustomElement.ts | 13 +++++-------- packages/runtime-dom/src/index.ts | 3 ++- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/packages/runtime-dom/__tests__/customElement.spec.ts b/packages/runtime-dom/__tests__/customElement.spec.ts index 1729129b1bb..1a4437ed360 100644 --- a/packages/runtime-dom/__tests__/customElement.spec.ts +++ b/packages/runtime-dom/__tests__/customElement.spec.ts @@ -17,7 +17,15 @@ describe('defineCustomElement', () => { describe('mounting/unmount', () => { const E = defineCustomElement({ - render: () => h('div', 'hello') + props: { + msg: { + type: String, + default: 'hello' + } + }, + render() { + return h('div', this.msg) + } }) customElements.define('my-element', E) @@ -30,13 +38,13 @@ describe('defineCustomElement', () => { }) test('should work w/ manual instantiation', () => { - const e = new E() + const e = new E({ msg: 'inline' }) // should lazy init expect(e._instance).toBe(null) // should initialize on connect container.appendChild(e) expect(e._instance).toBeTruthy() - expect(e.shadowRoot!.innerHTML).toBe(`
hello
`) + expect(e.shadowRoot!.innerHTML).toBe(`
inline
`) }) test('should unmount on remove', async () => { diff --git a/packages/runtime-dom/src/apiCustomElement.ts b/packages/runtime-dom/src/apiCustomElement.ts index 31302e13b06..fe3f594f69e 100644 --- a/packages/runtime-dom/src/apiCustomElement.ts +++ b/packages/runtime-dom/src/apiCustomElement.ts @@ -23,8 +23,8 @@ import { import { camelize, extend, hyphenate, isArray, toNumber } from '@vue/shared' import { hydrate, render } from '.' -type VueElementConstructor

= { - new (): VueElement & P +export type VueElementConstructor

= { + new (initialProps?: Record): VueElement & P } // defineCustomElement provides the same type inference as defineComponent @@ -134,8 +134,8 @@ export function defineCustomElement( static get observedAttributes() { return attrKeys } - constructor() { - super(Comp, attrKeys, propKeys, hydate) + constructor(initialProps?: Record) { + super(Comp, initialProps, attrKeys, propKeys, hydate) } } @@ -163,10 +163,6 @@ const BaseClass = ( ) as typeof HTMLElement export class VueElement extends BaseClass { - /** - * @internal - */ - _props: Record = {} /** * @internal */ @@ -178,6 +174,7 @@ export class VueElement extends BaseClass { constructor( private _def: ComponentOptions & { styles?: string[] }, + private _props: Record = {}, private _attrKeys: string[], private _propKeys: string[], hydrate?: RootHydrateFunction diff --git a/packages/runtime-dom/src/index.ts b/packages/runtime-dom/src/index.ts index 8a3012c20d1..f6f0cf322c4 100644 --- a/packages/runtime-dom/src/index.ts +++ b/packages/runtime-dom/src/index.ts @@ -198,7 +198,8 @@ function normalizeContainer( export { defineCustomElement, defineSSRCustomElement, - VueElement + VueElement, + VueElementConstructor } from './apiCustomElement' // SFC CSS utilities