javascript - Vue Component: Dropdown menu open inside div - Stack Overflow

I’m building a dropdown ponent for my project. But when i add the ponent is a responsive table the menu

I’m building a dropdown ponent for my project. But when i add the ponent is a responsive table the menu is open within the div.

Here is my code: =%2Fsrc%2FApp.vue

How can i make the dropdown-menu to append to the body and set a transform(x,y)

I’m building a dropdown ponent for my project. But when i add the ponent is a responsive table the menu is open within the div.

Here is my code: https://codesandbox.io/s/fast-pond-pto57t?file=%2Fsrc%2FApp.vue

How can i make the dropdown-menu to append to the body and set a transform(x,y)

Share Improve this question asked Oct 5, 2022 at 8:05 CodeAgentCodeAgent 1033 silver badges9 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 2

Try with position: fixed !important;:

new Vue({
  el: "#demo",
  data() {
    return {
      showMenu: false,
    };
  },
})
.dropdown-menu {
  position: fixed !important;
}
<script src="https://cdnjs.cloudflare./ajax/libs/vue/2.5.17/vue.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">
<div id="demo">
  <div class="table-responsive">
    <table class="table table-bordered">
      <thead>
        <tr>
          <th>#</th>
          <th>Name</th>
          <th>Action</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>1</td>
          <td>Joe Band</td>
          <td>
            <div class="dropdown">
              <button class="dropdown-toggle" @click="showMenu = !showMenu">
                Action
              </button>
              <ul class="dropdown-menu" :class="{ show: showMenu }">
                <li><a>Item 1</a></li>
                <li><a>Item 2</a></li>
                <li><a>Item 3</a></li>
              </ul>
            </div>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

I find both existing answers valuable, but neither plete:

  • TripleN's answer doesn't position the dropdown correctly
  • Nikola's answer doesn't append .dropdown-menu to <body>, so it stops working as soon as one of the ancestors of .dropdown has any valid transform value other than none (spec ref). Here's an example.

In my estimation, the correct solution would be to do both:

  1. allow Popper (used internally by Bootstrap 5) to position the dropdown (the popper content) correctly,
  2. append the popper content to <body> while dropdown is open.

That's pretty much it!
This particular task used to be easy in prior versions of Bootstrap. I've spent hours going through Bootstrap 5's and Popper's documentation and examples, trying to find a way to do this simple task: specify a target container for popper content.

If someone knows how to achieve this in Bootstrap 5 without having to meddle with DOM ourselves, I'd be delighted to learn how.
Eventually I gave up and ended up moving the menu in DOM myself, after Popper positions it:

Working demo.
In more detail, this hybrid solution:

  • uses Nikola's idea to give the menu position: fixed, so Popper does the heavy lifting of positioning
  • uses TripleN's idea to append the menu to <body>, after Popper positioned it. Additionally, I'm moving the menu back to its original place in DOM once the dropdown is closed. It might not be necessary, but to me it makes a lot of sense. Common sense.

The solution seems to work in all cases, including inside 3d transformed ancestors. I've smoke tested it in both latest Vue 2 (2.7.10) and latest Vue 3 (3.2.40). Does the job.

Same exact logic in Composition.


Side note: perhaps I'm too demanding but, by parison with prior versions, I find Bootstrap 5 difficult to work with and poorly documented, at least at this point in time.

This should have been a trivial task. Specify container: 'body' in Dropdown's config. Done!

I'm a bit disappointed.

Split dropdown menu into other ponent, in mounted hook use document.body.appendChild drowdown menu elemement (this.$el). I have already updated in this sandbox.

Hope this help!

This sounds like a good use case for vue 3's teleport ponent. By specifying a target element, you can tell Vue to send that element to the target element.

For example:

<Teleport to='body'>... this content will be sent to the body</Teleport>

The to property can be any valid selector or even a ref to another element.

You can also use the disabled property to programmatically disable the teleport. In this case the content of the ponent will remain where it was original placed.

If you're not using VUE 3, you can still very easily bang out a ponent that will mimic this same behavior. The teleport is great for things like modals, because it allows you to break free from the positioning constraints imposed by having a nested element.

For more information, check out the documentation for the teleport ponent.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744807432a4594861.html

相关推荐

  • javascript - Vue Component: Dropdown menu open inside div - Stack Overflow

    I’m building a dropdown ponent for my project. But when i add the ponent is a responsive table the menu

    2天前
    30

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信