One additional day of testing around - I think I found a good-enough solution to break free from the stacking context issue:
Steps I've taken:
Add a reference to the dropdown to use later on - not on the dropdown-menu
or the dropdown-toggle
button, see next step why:
<span class="dropdown" ref="dropdown">...</span>
Add an event listener for show.bs.dropdown
to this reference. This event will be triggered as soon as someone wants to activate the dropdown. As it bubbles up the hierarchy, we needed to set it to the dropdown container itself, and not to the dropdown-menu
, or the button with dropdown-toggle
where it is fires.
I've added the logic to the mounted()
function:
mounted() {
this.$refs.dropdown.addEventListener('show.bs.dropdown', this.moveDropdownToBody)
}
As soon as the event is triggered, move the dropdown-menu
out of the stacking context and to the body
to break free:
methods: {
moveDropdownToBody: function() {
document.body.prepend(
this.$refs.dropdown.querySelector(':scope > .dropdown-menu')
)
this.$refs.dropdown.removeEventListener('show.bs.dropdown', this.moveDropdownToBody)
}
}
I've cleaned the event listener up afterwards to save a bit performance as we only need to move the menu once.
Why using the event to only move the menu after the user clicked and not directly on initialization? Well, I got plenty of positioning issues. If initialized manually, many features like auto-positioning, facing automatically up or down based on the boundary, auto closing etc. won't work.
Bootstrap needs the "original context" to work as expected. Manually reproducing it is just too much hassle.
The code presented is also way smaller and easier to read :)
Hope it helps anyone facing the same issue.
Please comment or add an answer if you find a cleaner solution.