Exposed properties are not settable
Vue version
3.5.22
Link to minimal reproduction
https://play.vuejs.org/#eNp9U01v2zAM/SuCMMA2mjnDtlPmBFuDHLLDNmw7Cmhdm3bU2pKhDzdF4P9e2pKcBCiqg0GT75GPpHSiP7ou7S3QFc10oXhnNkzwtpPKkBNRUC1ICRUXsLXayHbXQAvCLMiBDKRSsiURkiMmisuwTh0njtqXj4W0woCK3kwUn5ggeETewopE24B1Xg3GdvHdApXAsZMayJAQzyCkkEIb/E4Ush7Fxp8/Jd+YCAhHCjXGU8PMiDEVcoxVIrjSPm8sFvHlvYSZ0I+Ma+ia9DgIfwJrSILl02Op9YYc4qjkPc7h/sPpKstw7wkDE0OCdracV4E/znbDQA8hlRWF4VIQLgrlxpj4Hkt4sHUNyv/Jwo7hFNv2A7992Zcxo74+o0nqzZsbHNwk4bq6gbZrcgNT5QwbILxcM2pAG0YnJ7rPa3bROf0mW55jAf1gjUH134uGF0+InttA/D7Y2dLBXN0lFkYrW17IoQtqNF6Citfpo5YCr/A0hbF82/EG1O9uHJNmdBVuDaN508jnn5PPKAt+1cg5QPH0hv9RH0cfo38UaFA9MDrHTK5wsi68+/cLjmjPwVaWtkH0O8G/oGVjR40OdmtFibIvcJPa/fQcuaj/693RgNChqVHotLQJzyg+xe07rZ/lfkm/+mUPdHgFVMZTdA==
Steps to reproduce
- Define a custom element
- Expose a settable property on it
- Try to set it's value
What is expected?
The value should be updated.
Even though the linked reproduction link is a stupid example and can be solved in other ways (props) I still think it would be nice to allow settable properties to expose some internal mechanism which can not be done using props.
From what I can see in the debugger this is how they are defined atm:
for (const key in exposed) {
if (!hasOwn(this, key)) {
Object.defineProperty(this, key, {
// unwrap ref to be consistent with public instance behavior
get: () => unref(exposed[key])
});
} else {
warn(`Exposed property "${key}" already exists on custom element.`);
}
}
As you see there is no setter defined here which puzzles me a little bit why that should be the case.
What is actually happening?
The set operation is ignored/causes a warning that the property is not settable.
System Info
Any additional comments?
No response
A summary of the changes CodeRabbit can apply:
Modify packages/runtime-dom/src/apiCustomElement.ts to import isRef and replace read-only exposed property definitions with getters plus setters that assign to ref.value for refs or update the exposed key for non-refs, and add tests verifying setting exposed ref properties, non-ref properties, and replacing exposed methods.
Add tests for setting exposed custom element properties and update apiCustomElement to make exposed properties writable (unwrapping refs on get, assigning to ref.value when a ref, or replacing non-ref values) so custom element exposures can be mutated from the element instance.
- [ ] ✅ Create PR with these edits
- [ ] 📋 Get copyable edits
a workaround - playground
I mean the provided workaround wouldn't provide the same API so I kind of disagree here.
You can however inherit the returned item and manually define additional properties this way, feels a bit unnecessary tbh and requires access to internals.