Tring to create a (semi) reusable Modal Component based on Bootstrap 5,with vuejs 3 and composible API. Managed to get it partially working,
Given (Mostly standard Bootstrap 5 modal, but with classes being added based on 'show' prop, and slots in body and footer):
<script setup lang="ts">
defineProps({
show: {
type: Boolean,
default: false,
},
title: {
type: String,
default: "<<Title goes here>>",
},
});
</script>
<template>
<div class="modal fade" :class="{ show: show, 'd-block': show }"
id="exampleModal" tabindex="-1" aria-labelledby="" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">{{ title }}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<slot name="body" />
</div>
<div class="modal-footer">
<slot name="footer" />
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
Close
</button>
</div>
</div>
</div>
</div>
</template>
and being 'called' by
<script setup lang="ts">
import { ref } from "vue";
import Modal from "@/components/Common/Modal.vue";
let modalVisible= ref(false);
function showModal(){
modalVisible.value = true;
}
</script>
<template>
<button @click="showModal">Show Modal</button>
<Modal title="Model title goes here" :show="modalVisible">
<template #body>This should be in the body</template>
<template #footer>
<button class="btn btn-primary">Extra footer button</button>
</template>
</Modal>
</template>
I get a modal 'shown' but the fade in animation doesn't work ,and the backdrop isn't visible, and the data-bs- buttons in the modal don't work ( i.e. it won't close). I feel its something to do with my whole approach.
NOTE. I cannot use a standard button with data-bs-toggle="modal" data-bs-target="#exampleModal" attributes as the actual trigger of this model comes from the logic of another component (as in just setting a bool), and the reusable modal component will be independent of its trigger --- it also doesn't feel the proper 'Vue' way to do it.
So I think I'm just 'showing' the html, and I need to instantiate a bootstrap modal somehow... just not sure how to do it
package.json (well the relavant ones)
"dependencies": {
"@popperjs/core": "^2.11.2",
"bootstrap": "^5.1.3",
"vue": "^3.2.31",
},
Code sand box here (Couldn't get the new Composition API and TS with working on code sandbox, so its a slight re-write with the standard options API approach, so code is slightly different, but exibits the same behaviour)
