-
-
Notifications
You must be signed in to change notification settings - Fork 8.8k
Description
Vue version
v3.5.18
Link to minimal reproduction
https://stackblitz.com/edit/vitejs-vite-nhmrulst?file=src%2Fmain.js
Steps to reproduce
I'm creating a custom datepicker control. Similar to the native <input type="datepicker">
control, I want to reject assignments to the value
property that aren't valid dates.
An easy solution would be to subclass the custom element:
const baseCustomElement = defineCustomElement({
props: { myProp: Date },
setup(props) { ... },
});
class DerivedCustomElement extends baseCustomElement {
set myProp(newValue) { if (isValid(newValue)) { super.myProp = newValue; } }
}
However, this doesn't work:
customElements.define("my-elem", DerivedCustomElement);
const elem = document.createElement("my-elem");
document.body.append(elem);
elem.myProp = "invalid value";
console.log(elem.myProp); // returns "invalid value"
What is expected?
DerivedCustomElement.myProp's setter should be called, and should not pass the new value into the component.
What is actually happening?
The setter is never called, because it is overridden when the component is mounted. This is done in apiCustomElement:_resolveProps. The comment, "// defining getter/setters on prototype", makes me think this is a bug.
An alternative solution for my use case would be to enforce prop validation in apiCustomElement, and not call _setProp if validation fails. However, this would have wider effects and would probably need more analysis, an option to toggle it off, and so on.
System Info
Any additional comments?
My proposed fix is to define the properties on the prototype, for real. In addition to making them overridable, this would probably also result in a small speedup, as they wouldn't have to be defined every time an instance is created and mounted.
I'd be happy to make a pull request for this, if accepted.