CSSTransition Component
https://codesandbox.io/s/thirsty-pasteur-m77l2vp00x?from-embed=&file=/index.js
by ChrisWong
HTML
<script src="https://unpkg.com/vue@next"></script>
<div id="app">
<div class="container" style="padding-top: 2rem">
<transition name="alert" mode="out-in">
<button v-if="!showAlert" @click="showAlert = true" type="button" class="btn btn-primary btn-lg">
Show Message
</button>
<div v-else role="alert" class="fade alert alert-primary alert-dismissible show alert-enter-done">
<button @click="showAlert = false" type="button" class="close">
<span aria-hidden="true">×</span><span class="sr-only">Close alert</span>
</button>
<div class="alert-heading h4">Animated alert message</div>
<p>This alert message is being transitioned in and out of the DOM.</p>
<button @click="showAlert = false" type="button" class="btn btn-primary">
Close
</button>
</div>
</transition>
</div>
</div>
SCSS
* {
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: transparent;
--blue: #007bff;
--indigo: #6610f2;
--purple: #6f42c1;
--pink: #e83e8c;
--red: #dc3545;
--orange: #fd7e14;
--yellow: #ffc107;
--green: #28a745;
--teal: #20c997;
--cyan: #17a2b8;
--white: #fff;
--gray: #6c757d;
--gray-dark: #343a40;
--primary: #007bff;
--secondary: #6c757d;
--success: #28a745;
--info: #17a2b8;
--warning: #ffc107;
--danger: #dc3545;
--light: #f8f9fa;
--dark: #343a40;
--breakpoint-xs: 0;
--breakpoint-sm: 576px;
--breakpoint-md: 768px;
--breakpoint-lg: 992px;
--breakpoint-xl: 1200px;
--font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI",
Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif,
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas,
"Liberation Mono", "Courier New", monospace;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
"Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji",
"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}
button {
font: 400 13.3333px Arial;
}
.container {
width: 100%;
max-width: 1140px;
padding-right: 15px;
padding-left: 15px;
margin-right: auto;
margin-left: auto;
}
.alert {
position: relative;
padding: 0.75rem 1.25rem;
margin-bottom: 1rem;
border: 1px solid transparent;
border-radius: 0.25rem;
}
.alert-primary {
color: #004085;
background-color: #cce5ff;
border-color: #b8daff;
}
.alert-dismissible .close {
position: absolute;
top: 0;
right: 0;
padding: 0.75rem 1.25rem;
color: inherit;
}
.alert-heading {
text-align: left;
box-sizing: border-box;
margin-bottom: 0.5rem;
font-weight: 500;
line-height: 1.2;
font-size: 1.5rem;
color: inherit;
}
.btn {
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: transparent;
--blue: #007bff;
...
JavaScript
const app = Vue.createApp({
data() {
return {
showAlert: false,
}
}
});
app.mount('#app');