0👍
This is a tricky bug in Ionic. It’s been around for a long time and they still haven’t solved it. See this GitHub issue for more details.
However, they don’t provide a resolution that works for everyone, and no solution for Vue. I’ve had some issues with IonMenu as well, so I figured I’d take a crack at the problem.
I modified your code, and it works in my environment. The gist of it is that the menu remains disabled after switching routes, and it is complicated by animations. I added a computed disabled
and onBeforeRouteLeave
handlers. I only had success with both in play. This required menus to have a menu-id
, and instead of making a bunch of props, I just used provide()
. My changes are below.
Dashboard.vue
<template>
<IonPage>
<Header />
<IonContent :fullscreen="true">
<span>Dashboard</span>
</IonContent>
</IonPage>
</template>
<script setup lang="ts">
import {IonContent, IonPage, menuController} from "@ionic/vue";
import Header from "../components/Header.vue";
import {onBeforeRouteLeave} from "vue-router";
import {provide} from "vue";
const menuId = "dashboard-menu"
provide("menu-id", menuId)
provide("route-name", "dashboard")
onBeforeRouteLeave(async () => {
await menuController.close(menuId)
await menuController.enable(true, menuId)
})
</script>
Profile.vue
<template>
<IonPage>
<Header />
<IonContent :fullscreen="true">
<span>Profile Page</span>
</IonContent>
</IonPage>
</template>
<script setup lang="ts">
import {IonContent, IonPage, menuController} from "@ionic/vue";
import Header from "../components/Header.vue";
import {onBeforeRouteLeave} from "vue-router";
import {provide} from "vue";
const menuId = "profile-menu"
provide("menu-id", menuId)
provide("route-name", "profile")
onBeforeRouteLeave(async () => {
await menuController.close(menuId)
await menuController.enable(true, menuId)
})
</script>
<style>
ion-modal {
--height: auto;
}
</style>
HeaderMenu.vue
<template>
<IonMenu side="end" :menu-id="menuId" content-id="main-content" :disabled="disabled">
<IonHeader>
<IonToolbar color="primary"></IonToolbar>
</IonHeader>
<IonContent>
<IonItemGroup>
<IonList class="ion-no-padding">
<IonMenuToggle>
<IonItem class="ion-text-center">
<IonButton
expand="full"
fill="clear"
size="small"
@click="navigate('dashboard')"
>
<span>Dashboard</span>
</IonButton>
</IonItem>
<IonItem class="ion-text-center">
<IonButton
expand="full"
fill="clear"
size="small"
@click="navigate('profile')"
>
<span>Profile</span>
</IonButton>
</IonItem>
</IonMenuToggle>
</IonList>
</IonItemGroup>
</IonContent>
</IonMenu>
</template>
<script setup lang="ts">
import {
IonHeader,
IonToolbar,
IonMenu,
IonMenuToggle,
IonContent,
IonButton,
IonList,
IonItem,
IonItemGroup,
} from "@ionic/vue";
import {computed, inject} from "vue";
import {useRouter} from "vue-router";
const routeName = inject("route-name")
const menuId: string = inject("menu-id")!
const router = useRouter()
const disabled = computed(() => {
return router.currentRoute.value.name !== routeName
})
const navigate = (routeName: string) => {
router.push({ name: routeName });
};
</script>
<style>
/* This fixes the issue with the menu not being clickable */
.menu-content-open {
pointer-events: unset !important;
}
</style>
- [Vuejs]-How can I register external component dynamically without any modification of parent(main) Project in vue3?
- [Vuejs]-How to connect to Google Calendar API from a browser using a service account?
0👍
I have see your code in HeaderMenu.vue page in IonToolbar component in set
your url and in defaultHref also set daynamic and static url(router).
ex:-
<ion-buttons slot="start">
<ion-back-button defaultHref="/" />
</ion-buttons>
- [Vuejs]-How to get Vite, TS, and Vue to properly work in vs-code
- [Vuejs]-How to insert other values into table column Vue3 Element-plus
0👍
Header being a component common to both of your pages, standard practice would be to move it outside of both and have <Header />
exist as a sibling just above <ion-router-outlet />
in App.vue
In order to not have the header and page content overlap each other, the router component needs to be wrapped with <IonContent>
<ion-app>
<Header />
<IonContent>
<ion-router-outlet id="main-content" />
</IonContent>
</ion-app>
Doing just these two things fixes your issue.