expect(el.hasAttribute('not-prop')).toBe(false)
})
+ test('handle properties set before connecting', () => {
+ const obj = { a: 1 }
+ const E = defineCustomElement({
+ props: {
+ foo: String,
+ post: Object
+ },
+ setup(props) {
+ expect(props.foo).toBe('hello')
+ expect(props.post).toBe(obj)
+ },
+ render() {
+ return JSON.stringify(this.post)
+ }
+ })
+ customElements.define('my-el-preconnect', E)
+ const el = document.createElement('my-el-preconnect') as any
+ el.foo = 'hello'
+ el.post = obj
+
+ container.appendChild(el)
+ expect(el.shadowRoot.innerHTML).toBe(JSON.stringify(obj))
+ })
+
// https://github.com/vuejs/core/issues/6163
test('handle components with no props', async () => {
const E = defineCustomElement({
)
}
this.attachShadow({ mode: 'open' })
+ if (!(this._def as ComponentOptions).__asyncLoader) {
+ // for sync component defs we can immediately resolve props
+ this._resolveProps(this._def)
+ }
}
}
}
}).observe(this, { attributes: true })
- const resolve = (def: InnerComponentDef) => {
+ const resolve = (def: InnerComponentDef, isAsync = false) => {
const { props, styles } = def
- const declaredPropKeys = isArray(props) ? props : Object.keys(props || {})
// cast Number-type props set before resolve
let numberProps
}
this._numberProps = numberProps
- // check if there are props set pre-upgrade or connect
- for (const key of Object.keys(this)) {
- if (key[0] !== '_' && declaredPropKeys.includes(key)) {
- this._setProp(key, this[key as keyof this], true, false)
- }
- }
-
- // defining getter/setters on prototype
- for (const key of declaredPropKeys.map(camelize)) {
- Object.defineProperty(this, key, {
- get() {
- return this._getProp(key)
- },
- set(val) {
- this._setProp(key, val)
- }
- })
+ if (isAsync) {
+ // defining getter/setters on prototype
+ // for sync defs, this already happened in the constructor
+ this._resolveProps(def)
}
// apply CSS
const asyncDef = (this._def as ComponentOptions).__asyncLoader
if (asyncDef) {
- asyncDef().then(resolve)
+ asyncDef().then(def => resolve(def, true))
} else {
resolve(this._def)
}
}
+ private _resolveProps(def: InnerComponentDef) {
+ const { props } = def
+ const declaredPropKeys = isArray(props) ? props : Object.keys(props || {})
+
+ // check if there are props set pre-upgrade or connect
+ for (const key of Object.keys(this)) {
+ if (key[0] !== '_' && declaredPropKeys.includes(key)) {
+ this._setProp(key, this[key as keyof this], true, false)
+ }
+ }
+
+ // defining getter/setters on prototype
+ for (const key of declaredPropKeys.map(camelize)) {
+ Object.defineProperty(this, key, {
+ get() {
+ return this._getProp(key)
+ },
+ set(val) {
+ this._setProp(key, val)
+ }
+ })
+ }
+ }
+
protected _setAttr(key: string) {
let value = this.getAttribute(key)
const camelKey = camelize(key)