BModal
A light-weight directive for showing modals by ID. It provides a semantically clear way to trigger modals and automatically handles accessibility attributes and trigger registration
The
v-b-modaldirective provides a simple, declarative way to showBModalcomponents. The directive automatically handles accessibility and provides a semantic alternative to the more generalv-b-toggledirective.
<div>
<BButton
v-b-modal.modal-overview
variant="primary"
>Show Modal</BButton
>
<BModal
id="modal-overview"
title="Hello Modal!"
>
<p>This modal can be triggered with the v-b-modal directive.</p>
</BModal>
</div>Overview
Things to know when using the modal directive:
- The directive works exclusively with
BModalcomponents - Target modals are specified by their
idattribute - Multiple modals can be shown simultaneously
- The directive automatically manages ARIA accessibility attributes
- The trigger element receives
collapsedandnot-collapsedCSS classes based on modal state - Disabled buttons will not trigger modal events
v-b-modalis an alias forv-b-toggle- both work identically butv-b-modalis semantically clearer for modals
Target Specification
The v-b-modal directive offers flexible ways to specify target modals:
Using Modifiers
The most common approach is using modifiers, where each modifier represents a modal ID:
<div>
<BButton
v-b-modal.my-modal
variant="primary"
>Open Modal</BButton
>
<BModal
id="my-modal"
title="Using Modifiers"
>
<p>The modal ID is specified as a modifier: <code>.my-modal</code></p>
</BModal>
</div>Using Directive Argument
You can specify the target as a directive argument (supports Vue's dynamic arguments):
<div>
<BButton
v-b-modal:modal-arg
variant="primary"
>Open Modal</BButton
>
<BModal
id="modal-arg"
title="Using Directive Argument"
>
<p>The modal ID is specified as an argument: <code>:modal-arg</code></p>
</BModal>
</div>Using Directive Value
The directive value can be a string ID or an array of IDs:
<div>
<div class="d-flex gap-2 mb-3">
<BButton
v-b-modal="'modal-value'"
variant="primary"
>String Value</BButton
>
<BButton
v-b-modal="['modal-value']"
variant="success"
>Array Value</BButton
>
</div>
<BModal
id="modal-value"
title="Using Directive Value"
>
<p>The modal ID can be specified as a string or array value.</p>
</BModal>
</div>All Methods
Here are all the ways to specify targets:
<!-- Using modifiers: Chain modifiers for multiple modals -->
<BButton v-b-modal.target-1.target-2>Toggle Multiple</BButton><!-- Using directive argument -->
<BButton v-b-modal:my-modal>Open Modal</BButton>
<!-- Dynamic argument (Vue 3+) -->
<BButton v-b-modal:[dynamicId]>Open Dynamic Modal</BButton><!-- Using string value -->
<BButton v-b-modal="'my-modal'">Open Modal</BButton>
<!-- Using array value for multiple modals -->
<BButton v-b-modal="['modal-1', 'modal-2']">Open Multiple</BButton>
<!-- Space-separated string for multiple modals -->
<BButton v-b-modal="'modal-1 modal-2'">Open Multiple</BButton><!-- Using href on links -->
<blink
v-b-modal
href="#my-modal"
@click.prevent
>Open Modal</blink
>
<a
v-b-modal
href="#my-modal"
@click.prevent
>Open Modal</a
><!-- Combined: modifier + argument + value -->
<BButton v-b-modal:another-modal.my-modal="'third-modal'"> Open Three Modals </BButton>Multiple Modals
Show multiple modals simultaneously using any of these methods:
<template>
<!-- #region template -->
<div>
<div class="d-flex gap-2 mb-3">
<BButton
v-b-modal.modal-1.modal-2
variant="primary"
>Using Modifiers</BButton
>
<BButton
v-b-modal="'modal-1 modal-2'"
variant="success"
>Space-separated String</BButton
>
<BButton
v-b-modal="['modal-1', 'modal-2']"
variant="info"
>Array Value</BButton
>
</div>
<BModal
id="modal-1"
title="First Modal"
>
<p>This is the first modal.</p>
</BModal>
<BModal
id="modal-2"
title="Second Modal"
>
<p>This is the second modal.</p>
</BModal>
</div>
<!-- #endregion template -->
</template>Using on Links
When the directive is applied to an <a> tag or BLink, the target can be specified via the href attribute:
<div>
<div class="d-flex gap-2 mb-3">
<BLink
v-b-modal
href="#modal-link"
@click.prevent
>BLink with href</BLink
>
<a
v-b-modal
href="#modal-link"
@click.prevent
>Anchor with href</a
>
</div>
<BModal
id="modal-link"
title="Triggered from Link"
>
<p>The modal ID can be extracted from the <code>href</code> attribute.</p>
</BModal>
</div>URL Navigation
Without @click.prevent, clicking the link will change the browser URL. Add @click.prevent to prevent this behavior while still showing the modal.
Conditional CSS Classes
The directive automatically adds CSS classes to the trigger element based on the modal's visibility state:
collapsed- Added when the modal is hiddennot-collapsed- Added when the modal is visible
You can use these classes to conditionally style the trigger:
.collapsed .when-open { display: none; } .not-collapsed .when-closed { display: none; }Disabled State
Disabled elements will not trigger modals:
<!-- This button will not trigger the modal when disabled -->
<BButton
v-b-modal.my-modal
:disabled="true"
>
Disabled Button
</BButton>Comparison with Other Approaches
The v-b-modal directive is one of several ways to control modals. Choose the approach that best fits your use case:
Using v-b-modal Directive
Using v-model
Using Template Refs
Using useModal Composable
<template>
<div>
<h5>Using v-b-modal Directive</h5>
<BButton
v-b-modal.modal-directive
variant="primary"
class="mb-3"
>
Open with Directive
</BButton>
<BModal
id="modal-directive"
title="Directive Approach"
>
<p class="card-text">Simple, declarative approach for triggering modals.</p>
</BModal>
<h5>Using v-model</h5>
<BButton
variant="success"
class="mb-3"
@click="showVModel = true"
>
Open with v-model
</BButton>
<BModal
v-model="showVModel"
title="v-model Approach"
>
<p class="card-text">Direct control via reactive state binding.</p>
<p class="mb-0">Current state: {{ showVModel ? 'Visible' : 'Hidden' }}</p>
</BModal>
<h5>Using Template Refs</h5>
<BButton
variant="info"
class="mb-3"
@click="modalRef?.show()"
>
Open with Template Ref
</BButton>
<BModal
ref="modalRef"
title="Template Ref Approach"
>
<p class="card-text">Programmatic control using component methods.</p>
<div class="d-flex gap-2 mt-3">
<BButton
size="sm"
variant="outline-primary"
@click="modalRef?.show()"
>Show</BButton
>
<BButton
size="sm"
variant="outline-secondary"
@click="modalRef?.hide()"
>Hide</BButton
>
<BButton
size="sm"
variant="outline-info"
@click="modalRef?.toggle()"
>Toggle</BButton
>
</div>
</BModal>
<h5>Using useModal Composable</h5>
<BButton
variant="warning"
class="mb-3"
@click="openComposableModal"
>
Open with Composable
</BButton>
</div>
</template>
<script setup lang="ts">
import {ref, useTemplateRef} from 'vue'
import {useModal} from 'bootstrap-vue-next/composables/useModal'
import {BModal} from 'bootstrap-vue-next/components/BModal'
import {type ComponentExposed} from 'vue-component-type-helpers'
// v-model approach
const showVModel = ref(false)
// Template ref approach
const modalRef = useTemplateRef<ComponentExposed<typeof BModal>>('modalRef')
// Composable approach
const modal = useModal()
const openComposableModal = () => {
modal
.create({
body: 'This modal was created dynamically using the useModal composable.',
title: 'Composable Approach',
})
.show()
}
</script>When to Use Each Approach
Use v-b-modal directive when:
- You need a simple, declarative way to trigger modals
- The trigger element is separate from modal state management
- You want automatic accessibility handling
- You're triggering modals from static elements (buttons, links)
Use v-model when:
- You need two-way binding with modal visibility
- Modal state is part of your component's reactive data
- You want to react to modal visibility changes
- You need to control the modal from multiple places
Use template refs when:
- You need programmatic control with explicit method calls
- You want access to the full component API (
show(),hide(),toggle()) - You're building wrapper components
- You need to call methods from lifecycle hooks or watchers
Use useModal composable when:
- You need to create modals dynamically
- You're building message boxes or confirmation dialogs
- You need to return values from modals (Promise-based API)
- You want to show modals without declaring them in the template
Accessibility
The directive automatically handles accessibility by setting and managing ARIA attributes:
What the Directive Manages
The v-b-modal directive sets:
aria-controls- Lists the IDs of all target modals (static, set once)
What the Modal Component Manages
The modal component manages:
aria-expanded- Reflects current visibility state ('true'or'false')
The directive itself handles the CSS classes (collapsed/not-collapsed) and click event handlers on the trigger element.
This separation of responsibilities ensures consistent accessibility across all show/hide components. For detailed information, see the ARIA Visibility Architecture documentation.
Best Practices
- Only use the directive on keyboard-focusable elements (buttons, links, form controls)
- Avoid applying to decorative elements like
<div>or<span>unless you also add appropriate ARIA attributes and keyboard handling yourself - For elements that don't have a native role of
buttonorlink, manually add an appropriaterole(for example,role="button") and atabindex(such astabindex="0") so they are keyboard-focusable
Related Components
- BModal Component - Full modal component documentation
- v-b-toggle Directive - The underlying directive (v-b-modal is an alias)
- useModal Composable - For creating modals dynamically