Subscribe on changes!

Using v-model on a custom Element (from defineCustomElement): prop/event mismatch

avatar
Aug 24th 2021

Version

3.2.4

Reproduction link

CodeSandbox Link

Steps to reproduce

Create a custom input as a CustomElement and use it in a Vue component.

What is expected?

The value specified in the v-model changes

What is actually happening?

v-model is ignored.

avatar
Aug 24th 2021

Strictly speaking this is not really a bug as the custom element does what it's supposed to do: it emits the component event as a custom event. The problem is that v-model listens for input but the custom element emits an update:modelValue event.

However we should discuss how we can better support this common usecase.

avatar
Aug 24th 2021

On second thought, I'm inclined to rate this as a bug. There's a few different aspects to this, the thing to discuss is wethe we want to support v-model on a custom element at all. We currently support it on distinct native input elements only (and components, but we are dealing with a custom DOM element here).

If we decided to do this, we would have to make the v-model listener deal with custom events, where the emitted value is found in a detail property. This would complicate things quite a bit.

But regardless of that discussion, the thing that makes it a bug right now, though, is that there's no way to actually listen to the update:modelValue event though - because we explicitly skip these special events on DOM elements (because they get special treatment on native inputs).

https://github.com/vuejs/vue-next/blob/b40845153cd4dbdd76bfb74816f4e6b109c9f049/packages/runtime-dom/src/patchProp.ts#L30-L32

So even if the consumer doesn't use v-model and tries the following, they will fail:

<custom-element :model-value="value" @update:model-value="value = $event.detail"

...because the event listener is never being applied to the custom element. Which is desirable for normal DOM elements, of course, but poses an issue here.

I'll think a bit about it and write more thoughts later

avatar
Aug 24th 2021

The styles of child vue component are not applied if the parent component is a custom element. #4309 Because of this, I have to define my custom input as a custom element, otherwise I cannot use any styles.

I thank you for your help and hope that a solution/workaround will be found soon. 🙂

✌ue is awesome!

avatar
Mar 22nd 2022

I didn't want to create another issue for it, as this seems related:

v-model does not work on <component :is="..."> components either. Reproduction: https://codesandbox.io/s/customelement-v-model-bug-forked-w4p21s?file=/src/App.vue

For <component is="input"> one could use @input="value = $event.target.value" But I would have rather used v-model which worked in Vue 2

Bumped into this as my use case for this was single component for both textarea and input.

avatar
Nov 24th 2023

@LinusBorg Did you think about it? It's November 2023 and this is still an issue. It's also a regression from Vue 2.x (https://www.digitalocean.com/community/tutorials/how-to-add-v-model-support-to-custom-vue-js-components) and is blocking me personally from achieving my goal of creating custom elements that do support v-model (like a custom for example).

avatar
Dec 20th 2023

I have a PR up that addresses this issue (at least partially) for custom elements.

It allows you to specify a v-model type for different custom elements (like checkbox, radio, etc.). Library authors will need to mirror native input props (e.g. value, checked) and input/change events (while also mirroring changes to value/checked on the host element so that updated values are in event.target), but it'll be possible to make v-model form bindings work across different types of custom elements.