Skip to content

Vue3 with UIkit's modal issue (contains: issue explanation and workaround) #432

@dugzino

Description

@dugzino

Issue

Explanation

Since UIkit manipulates the DOM to be able to bring modals on top of everything (by moving it from the component element to the top in the body), it brings up an issue with Vue (and probably other frameworks) that when switching routes, it can't destroy the modal as it is not part of it anymore. So to resolve that issue, you will need to manipulate the DOM when unmounting the component. Find the modal's ID and remove it from the DOM. Because if you don't, you'll be creating duplicates.

Using Vue's "ref" or "v-if" won't remove it because as I said, it's not longer part of component.
So, you can even find yourself with an empty modal at some point, having to refresh the page to be able to see them.

Recreation

Have this in a view component:

<script setup>
const openModal = () => UIkit.modal("#some-modal").show()

<template>
  <button @click="openModal">Open modal</button>

  <div id="some-modal" uk-modal>
    <div class="uk-modal-body">Some content</div>
  </div>
</template>
  1. Go to that view live.
  2. Open modal. You can see it move out of the component in the DOM into the body
  3. Switch route and go back without using browser history
  4. Open modal. You'll see the component's modal move out the component and stacking with the previous modal on top in the body.

Fix (workaround)

In Vue3 it would be like:

<script setup>
  import { onUnmounted } from "vue"
  onUnmounted(() => {
    // The "?" usage is for edge cases if user moves through history back and forth without opening modal.
    document.getElementById("your-modals-id")?.remove()
  })
</script>

In this way it should be removed properly when switching routes.
Or have a UIkit.modal("id").remove() function that would do it for you. But I wouldn't recommend such a thing as it's an edge case situation. It probably only affects Vue for all I know.

I think this should be added to the doc as it's the only thing so far that did not work correctly for me on Vue.

Screenshots

Screenshot from 2024-07-27 15-29-40

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions