[framework] Improve vuejs support
@pskelin is already working on this.
Since May 22, 2025.
- Dominant language
- TypeScript
- Stars
- 1.8k
- Forks
- 285
- Avg merge
- 3d 2h
- Merged PRs (30d)
- 59
Description
There is some documentation about using web components with vuejs for the project, especially two-way data binding:
https://sap.github.io/ui5-webcomponents/docs/frameworks/Vue/#two-way-data-binding
There is however no code completion or type checking like for vue components. There is an experimental wrapper function that can create vue components based on web component classes described in this comment:
https://github.com/SAP/ui5-webcomponents/issues/11537#issuecomment-2894111013
It is still quite early and the following feedback should be incorporated. Ideally there should be a @ui5/webcomponents-vue package that exports all components similar to @ui5/webcomponents-react.
Thanks @pskelin for looking into it!
I played around with your wrapper function and got some feedback.
First of all, I think it's a very elegant solution, but the current implementation is still a bit restricting and does not provide a full working component in the end (debatable, see slots section).
In our internal library, we have created individual wrappers for each ui5 web-component, which off course adds a lot more of boiler-plate, and a simple wrapper function solution would make things easier, but on the other hand, we can fully detail how our component looks like, including props, events, exposed methods and slots. This also allows us to further create
v-model's for propertie other thenvalue(see component v-model).I decided to test the function with the Dialog component, just because it had multiple slots and also a method, in addition to props and events.
Props
The first thing that I noticed is that we have indeed type support, and types seems correct, but we also get a lot of properties and methods beginning with a
_, which makes me thing they areprivateorprotectedand probably shouldn't be listed in the type completion dropdown:
Another aspect immediately noticeable, is that because the component inherits all properties and methods from its ancestor, is really hard to pick apart which ones are defined by the Dialog component and which ones are inherited. Although not an issue per se, I do think nicer to be able to have that separation, because most of the time those are the methods and properties we will be looking for when working with a specific component. In our library, because we are redefining the component specific attributes, we can only see those in the autocompletion, and thn all the inherited methods will be available only if we use template refs, meaning that all of those "external" attributes actually belong to the
ui5-dialogcomponent, and not to ourDialog.vuecomponent.Events
The same thing happens for the events:
Slots
The current implementation of the wrapper has no type support/completion for slots:
For comparison, this is our current implementation for the Dialog:
Another issue with the current implementation of the wrapping function is that it only forwards default slots. So for the Dialog component, if I pass a header or a footer using the Vue's slot syntax, they are not forwarded, so only the default slot is renderer:
I think here is also worth noting that we took a different approach for the slots. We define Vue slots for our components just like the ui5-webcomponents slots, withe the help of a custom vite-plugin to add
slotattributes for the slotted elements. In that way, we can see the component defined slots and we don't need to manually add theslotattribute for those elements, making it easier to work with component slots, but I can see that maybe this would not be something that you guys would plan to do for your component library project, as it increases complexity.Note: I haven't tested it, but I'm sure it would work if we would add the slotted content inside Vue's default slot and then mark the individual slot targets with the
slotattribute. That just to say that the function should in theory work for every slot, but just not in a very "Vue" way (vue eslint plugin also complains when we use theslotattribute: vue/no-deprecated-slot-attribute )Template refs
Regarding template refs, the current implementation does not provide type for the component template refs. Vue offers a defineComponent to add types for a Vue component. I did experiment with it, modifying the createWrapper function, and indeed the types started showing:
One problem that I noticed though, and that even be an issue with the way I implemented it (sorry, didn't expend too much time looking into it) - or even with the wrapping function -, is that the types suggests that the webcomponent methods are available in the Vue component instance, when in reality they are not:
Component v-model
My last point, is regarding component v-model. This is also not an issue per se, just a nice-to-have. Because we manually write our wrappers, we can leverage Vue's defineModel macro to create custom v-models, like for example, for the Dialog's
openproperty:const modelOpen = defineModel('open');This allows to then in the application to use a 2-way binding to that property, keeping our data synchronized with the ui5-dialog
openproperty. But I'm not sure if that would be something easy to achieve with the wrapping function or if that's even something you plan to support at some point.Anyways, this turned out to be a way longer text than planned, so sorry for that! But I hope this can be helpful in one way or another.
Originally posted by @vonBrax in #11537
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.