core icon indicating copy to clipboard operation
core copied to clipboard

Exposed properties are not settable

Open dotlogix opened this issue 1 month ago • 3 comments

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

dotlogix avatar Nov 05 '25 03:11 dotlogix

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

coderabbitai[bot] avatar Nov 05 '25 03:11 coderabbitai[bot]

a workaround - playground

edison1105 avatar Nov 06 '25 03:11 edison1105

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.

dotlogix avatar Nov 14 '25 09:11 dotlogix