UI5 / UI5/webcomponents

[framework] Improve vuejs support

Open
#11,562 0 comments 3 reactions 1 assignee View on GitHub

@pskelin is already working on this.

Since May 22, 2025.

TOPIC Core
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 then value (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 are private or protected and probably shouldn't be listed in the type completion dropdown:

Image

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-dialog component, and not to our Dialog.vue component.

Events

The same thing happens for the events:

Image

Slots

The current implementation of the wrapper has no type support/completion for slots:

Image

For comparison, this is our current implementation for the Dialog:

Image

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:

Image

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 slot attributes for the slotted elements. In that way, we can see the component defined slots and we don't need to manually add the slot attribute 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 slot attribute. 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 the slot attribute: 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:

Image

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:

Image

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 open property:

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 open property. 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.