I have a sidebar component that works similar to a modal. When a button is clicked, the sidebar translates into the viewport with nav links. These nav links are actually router-links that are wired up to a vue-router.
What I'm trying to accomplish
When I click on a router-link that is inside my sidebar component, I want the sidebar to transition off the viewport and I want the clicked router-link's component to render without the page reloading.
What's currently happening
When I click on the router-link, the sidebar is removed instantly from the DOM. It does not translate off the screen as intended. Also, the page is reloaded.
What else have I tried
I also tried moving the <transition> wrapper inside TheSidebar.vue component along with the associated CSS classes, and I passed sidebarIsVisible as a prop from App.vue to TheSidebar.vue.
My code
A Codesandbox demo can be found here
App.vue
<template>
<router-view></router-view>
<button @click="toggleSidebar" class="toggleBtn">Toggle Sidebar</button>
<transition name="sidebar">
<the-sidebar
v-if="sidebarIsVisible"
@link-clicked="toggleSidebar"
></the-sidebar>
</transition>
</template>
<script>
import TheSidebar from "./components/TheSidebar.vue";
export default {
components: {
TheSidebar,
},
data() {
return {
sidebarIsVisible: false,
};
},
methods: {
toggleSidebar() {
this.sidebarIsVisible = !this.sidebarIsVisible;
},
closeSidebar() {
this.sidebarIsVisible = false;
},
},
};
</script>
<style>
/* basic styling */
.toggleBtn {
position: fixed;
top: 5px;
left: 5px;
}
.sidebar-enter-active {
animation: slide-sidebar 0.3s ease;
}
.sidebar-leave-active {
animation: slide-sidebar 0.3s ease reverse;
}
@keyframes slide-sidebar {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
</style>
TheSidebar.vue
<template>
<div class="sidebar">
<nav>
<ul>
<li>
<router-link @click="$emit('link-clicked')" to="/link1">
Link 1
</router-link>
</li>
<li>
<router-link @click="$emit('link-clicked')" to="/link2">
Link 2
</router-link>
</li>
</ul>
</nav>
</div>
</template>
<script>
export default {
emits: ["link-clicked"],
};
</script>
<style scoped>
/* basic styling */
</style>
main.js
import { createApp } from "vue";
import { createRouter, createWebHistory } from "vue-router";
import App from "./App.vue";
import LinkOne from "./components/LinkOne.vue";
import LinkTwo from "./components/LinkTwo.vue";
const app = createApp(App);
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: "/link1", component: LinkOne },
{ path: "/link2", component: LinkTwo }
]
});
app.use(router);
app.mount("#app");