Subscribe on changes!

Inconsistent behaviour between @update:modelValue and @update:model-value

avatar
Oct 17th 2022

Vue version

3.2.41

Link to minimal reproduction

https://sfc.vuejs.org/#__DEV__eNqVVFlr20AQ/iuDCJECtkTSPslOSB9a6EtbaGkfqkJka+Osoz3YXSkJRv+9s7OSfMTuQSDWXN9c3+wmeqd12jYsyqO5XRquHVjmGn1TSC60Mg5+mFJrZuDeKAFxmvWyD4pHp2/s2X2UunGj26jpHUfXDRh2P8F/5dLxlkHXhwQ3gEIulbQIxFldwfXomGy8VZaC5RCT8RN+xxOvbcu68WqrBOsDSeWt3UUh51noDbtCwTGh69IxlADmFW/pA+ADBX4PWJtNAEoJCLoOksZyuYLz2s04tepeNLsuIoedFtH5ys0wk8fZgUThiC+0U6EqVqNiJwfqsxvfP4VlHsR/UZEkBQvJw1Jyih9wCNnWyqHC/3wxStsi6gP3yvqKZiA7tfp5sWZLlz6yF5uMkRfpWnGZxBOIL3AAu4XRotx8u/YBt50uuPQF7eRHY+EKl4V5DwSiVufZuIxoEgWGTEWp07VVEjlJOy96A0Jhsf0UIuSLl4vowTnsIssaqR9X6VKJ7BZtmWmk44JNKyVu36RX6dtLrNy6XX3KrJgujHqyyOc1whOZevAMlS0zU8NkxQwzf0x24LuX8MD2KqnPicPtcAA7t3XkIMNdaD9UvIuK3XPJaMThNIgCeb/KfyM+WPdSe16K0qy4nDqlc7hiYjaSpq/o6D20vKRrGMiYnbwBT4ZBAMiJ/HRnhxcQmOL/bhtdYaknfXECZ6xlEs9pizy0s1AGZ53DpX4Gq2pewQJDZqDLqsIbRgMT2zh/dcNlnbq8faLuPW7/v6ltTzjXrl/VEMUEd2PQexRs8jN+NYz4F4Xsv6lPpVs+HDyoAXQYGbolVFa6hSIgCk3IbQIhG1zfhGvzEKpmaa1Wyd3Yet677RTlI4robBMMXRHdERt8R8mRFoZE6PQ3rtIjGsix95IG1fY5HWnkt7q/te43ozdZAA==

Steps to reproduce

The link provided demonstrates the "broken" behaviour. The (blue) wrapped input element does not have its value bound. Whatever you type in will not update the bound variable.

To fix this, in Wrapper.vue, change the @update:modelValue=... reference to @update:model-value=...

Now the input fields will have the value correctly bound, and you can update the value from the blue text input.

What is expected?

Wrapper.vue is passing back slot properties, one of which is @update:modelValue=...

However, in App.vue, when the slot property keys are dumped out, it can be seen that this is translated for some reason to on:update:modelValue, which appears to be meaningless as it never triggers.

It ought to be converted to onUpdate:modelValue but there appears to be some kind of specific conversion going on that only affects this string. The proof being that we can circumvent it by replacing it with @update:model-value=... which correctly gets converted to onUpdate:modelValue, and gets bound/registered/activated properly

All other @event properties are correctly converted to onEvent equivalents (i.e. @click converts to onClick etc)

What is actually happening?

There appears to be a specific replacement happening for @update:modelValue to convert it to on:update:modelValue which Vue then ignores (it never triggers)

System Info

No response

Any additional comments?

I am attempting to render some input element via a wrapper. The wrapper accepts a field and various other parameters, and generates lovely HTML for display, as well as providing v-slot properties back so they can be passed into the input component itself (which is passed in as a slot).

Part of the slot props being passed back is workaround for implementing v-model, i.e. :modelValue=... and @update:modelValue=...

However, when you look at the property names being returned (in App.vue), we see on:update:modelValue instead of onUpdate:modelValue, and also the update event never gets caught.

When this is changed in Wrapper.vue to @update:model-value, it's correctly passed back as onUpdate:modelValue and works nicely/properly.

Incidentally, I discovered this when I was converting my app to use Webpack preprocessing. Prior to this, I had all my .vue components accessible in a public directly and imported on-the-fly via this library: https://github.com/FranckFreiburger/vue3-sfc-loader, i.e. so the browser would directly request, transpile and import each component individually. This code worked perfectly with that. It's only in preprocessing via Webpack and/or Vite (and SFC playground) that this issue comes up