Skip to content

Commit 1a205ca

Browse files
committed
fix(runtime-dom): refactor for unit tests
1 parent 07ff2bf commit 1a205ca

File tree

2 files changed

+22
-22
lines changed

2 files changed

+22
-22
lines changed

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

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,7 +1442,7 @@ describe('defineCustomElement', () => {
14421442
expect(e.shadowRoot!.innerHTML).toBe('<div>another-valid</div>')
14431443
})
14441444

1445-
test('properties are defined on prototype not instance', () => {
1445+
test('properties are defined on instance for backward compatibility', () => {
14461446
const E = defineCustomElement({
14471447
props: {
14481448
testProp: String,
@@ -1460,14 +1460,12 @@ describe('defineCustomElement', () => {
14601460
container.appendChild(e1)
14611461
container.appendChild(e2)
14621462

1463-
// Properties should be defined on the prototype, not instances
1464-
expect(e1.hasOwnProperty('testProp')).toBe(false)
1465-
expect(e1.hasOwnProperty('anotherProp')).toBe(false)
1466-
expect(Object.hasOwnProperty.call(E.prototype, 'testProp')).toBe(true)
1467-
expect(Object.hasOwnProperty.call(E.prototype, 'anotherProp')).toBe(true)
1463+
// Properties should be defined on instances for backward compatibility
1464+
expect(e1.hasOwnProperty('testProp')).toBe(true)
1465+
expect(e1.hasOwnProperty('anotherProp')).toBe(true)
14681466

14691467
// Properties should have getter and setter functions
1470-
const descriptor = Object.getOwnPropertyDescriptor(E.prototype, 'testProp')
1468+
const descriptor = Object.getOwnPropertyDescriptor(e1, 'testProp')
14711469
expect(descriptor).toBeDefined()
14721470
expect(typeof descriptor!.get).toBe('function')
14731471
expect(typeof descriptor!.set).toBe('function')

packages/runtime-dom/src/apiCustomElement.ts

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,10 @@ export class VueElement
431431
const exposed = this._instance && this._instance.exposed
432432
if (!exposed) return
433433
for (const key in exposed) {
434-
if (!hasOwn(this, key)) {
434+
const hasInstanceProperty = hasOwn(this, key)
435+
const hasOwnPrototypeProperty = hasOwn(this.constructor.prototype, key)
436+
437+
if (!hasInstanceProperty && !hasOwnPrototypeProperty) {
435438
// exposed properties are readonly
436439
Object.defineProperty(this, key, {
437440
// unwrap ref to be consistent with public instance behavior
@@ -460,23 +463,12 @@ export class VueElement
460463
}
461464
}
462465

463-
// defining getter/setters on prototype to allow subclass overrides
466+
// defining getter/setters to support property access
464467
for (const key of declaredPropKeys.map(camelize)) {
465-
// Always define the Vue property on the current prototype, but check if a parent
466-
// class in the prototype chain already has the property defined by a subclass.
467-
// This ensures super.property calls work while allowing subclass overrides.
468+
// Check if a subclass has already defined this property
468469
const hasSubclassOverride = this.constructor.prototype.hasOwnProperty(key)
469470

470-
if (!hasSubclassOverride) {
471-
Object.defineProperty(this.constructor.prototype, key, {
472-
get() {
473-
return this._getProp(key)
474-
},
475-
set(val) {
476-
this._setProp(key, val, true, true)
477-
},
478-
})
479-
} else {
471+
if (hasSubclassOverride) {
480472
const parentPrototype = Object.getPrototypeOf(
481473
this.constructor.prototype,
482474
)
@@ -494,6 +486,15 @@ export class VueElement
494486
},
495487
})
496488
}
489+
} else {
490+
Object.defineProperty(this, key, {
491+
get() {
492+
return this._getProp(key)
493+
},
494+
set(val) {
495+
this._setProp(key, val, true, true)
496+
},
497+
})
497498
}
498499
}
499500
}
@@ -506,6 +507,7 @@ export class VueElement
506507
if (has && this._numberProps && this._numberProps[camelKey]) {
507508
value = toNumber(value)
508509
}
510+
509511
this._setProp(camelKey, value, false, true)
510512
}
511513

0 commit comments

Comments
 (0)