-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
v-model support for web components (stenciljs) #7830
Comments
I tracked this down a bit and seems to come from how Vue treats custom components differently than a regular element like an For regular inputs, Vue looks for the value in For custom components like ion-input, it seems that Vue is expecting the value to be emitted directly and not as a subclass of Event. So, Vue looks for the value in This behaviour is documented here: https://vuejs.org/v2/guide/components.html#Using-v-model-on-Components This was probably done to make the coding of custom components simpler: the developer wouldn't need to instantiate a new Event and emit it. A simple fix (and uneducated guess on my part) would be to get rid of the special case for custom components and check if what is being |
Leaving a comment here as it may be helpful to others, whilst this definitely should be handled inside the vue project itself in the meantime if you're looking for a solution right now I've created a compile directive that is configurable and allows you to use the same syntax on web-components until a proper solution is in place: https://www.npmjs.com/package/vue-wc-model I wouldn't mind creating a PR and getting something implemented in vue itself but there is some unknowns regarding how this should be handled. For example, not all web components use the I think this needs to be thought out some more in terms of what to do. |
What if
Could even be used for custom event names (as long as they didn't contain any colons or periods) Any event specified this way would set the model value to |
Has anyone began to investigate this. This has had a huge impact on us in moving forward with using Vue. It also appears that Vue is the only framework where we are seeing binding issues with our web components. |
I really like the idea of |
We've also trying to use WebComponents with Vue. The problem here is, Vue must know this WebComponent implemented |
That imho is not a good option name, should be more self-explanatory. How about |
Why should there be an extra modifier/directive? The For regular inputs Vue uses |
@ngfk 's solution looks better to me. No change to current api, and nothing should break in this way. |
Note there are currently two 3.0 RFCs that uses the In RFC#31 there is a section that talks about The problem with |
I created a custom directive that makes this less painful. Suggestions or improvements are welcome! // model-custom-element.js
import Vue from 'vue';
const wm = new WeakMap();
export default {
bind(el, binding, vnode) {
const inputHandler = event => Vue.set(vnode.context, binding.expression, event.target.value);
wm.set(el, inputHandler);
el.value = binding.value;
el.addEventListener('input', inputHandler);
},
componentUpdated(el, binding) {
el.value = binding.value;
},
unbind(el) {
const inputHandler = wm.get(el);
el.removeEventListener(el, inputHandler);
}
}; // main.js
import modelCustomElement from './model-custom-element.js';
// ... your vue init here
Vue.directive('model-custom-element', modelCustomElement); <!-- Usage example -->
<flux-textfield v-model-custom-element="name"></flux-textfield> |
@claviska I just used your code and adapted it to my custom WC input ;-) Thanks a lot!!! 🎉 I had to do add naïve support for "dot notation" and since I already had lodash in the project, I used its |
The current situation with In the second case, the component seemingly needs to watch (f.ex) both of My preference if it's possible would be to allow components to override the default model value binding with a new top-level property on the definition, maybe something like this: export const MyComp = defineComponent({
props: { value: String },
modelValue: "value",
setup(props, ctx) { .. }
}) With this definition writing This change would also allow the default model value binding for that component to be changed later on without updating all invocations of the component, for example to bind by default to a live |
This is great! Thank you! |
Here is a detailed article on how to support v-model with web components using a custom directive. https://muhimasri.com/blogs/how-to-create-custom-v-model-for-web-components/ Cheers |
@claviska @muhimasri Thank you for awesome solutions. Do you have any idea how to do the same in Vue3? |
You are welcome @rahmanroman I will look into making it work in Vue3. As you mentioned, the |
Thanks for this, works pretty well for primitive based models :)
By this (using lodash) :
|
this still happens in 2023,gods... |
Extremely late to the party here, but thought i'd add some learned knowledge for anyone arriving via google (and also future me!). As long as your component raises an <script setup>
const value = ref(0)
</script>
<template>
<p>value from v-model: {{ value }}</p>
<my-counter v-model="value"></my-counter>
</template> If your component uses a Here's a working example https://stackblitz.com/edit/vue-web-component-v-model?file=src%2FApp.vue |
yeah i don't know how but it started working for me as well with shoelace. Can't find any specific v-model updates in the latest releases but I'm super glad it works |
What problem does this feature solve?
V-model support for web components(tested with web component implemented with ionic's stenciljs compiler).
Does not work:
Works:
Can this be enabled to support ignored elements as well that have been declared with:
Vue.config.ignoredElements = [/^ui-/];
What does the proposed API look like?
Declaration
Usage
The text was updated successfully, but these errors were encountered: