Open lazlo-bonin opened 6 years ago
You are missing that the class that you define on the component will be added to its root element - which is the portal, not the div inside it.
However, you can set inheritAttrs: false
in the component containing the portal and then use $attrs to pass any attributes defined in the component to that div instead:
<div class="dialog-mask" v-bind="$attrs">
Please see the Vue documentation for those two properties of you want to learn more.
The Vue documentation states:
Note: this option does not affect class and style bindings.
Any other solution?
Edit: Seeing this issue, I ended up using a custom prop after all:
Oh, right, forgot about that limitation.
I will add this to the caveats section in the docs later.
If the dialog has a single root element, wouldn't the slim
option make the inner content the root element (this.$el) and the class would be placed in it? or is that relationship lost during transport?
Just realized that slim is only applicable to disabled
mode.
I also tried setting portal's tag to transition
(which has the nice effect of rendering <!---->
instead of a visually hidden div
), but still the same effect of not transferring the class to the root element.
or is that relationship lost during transport
This. There's really no way to make this work.
It feels hacky but i solved this using $vnode.data.staticClass
<template>
<portal to="root">
<div :class="$vnode.data.staticClass" />
</portal>
</template>
This way class (and potentially any data inside vnode) can be pass down through the portal
I use portal-vue in order to move all my modals at the top level for z-ordering. My dialog component setup is like so:
When I try to use the component, I often do something like:
However, when the
<div>
is rendered in theportal-target
, it only has thedialog-mask
class, notdialog-mask myDialogClass
.I'm struggling to get the class property to bind. I could use a custom dialogClass prop and do it manually, but I'd rather use vue's built-in clear syntax.
Am I missing something?