I am building a SPA with Vue 3 and now I have the case that I would like to show a badge in the navbar of certain pages. My structure:
// App.vue
<template>
<NavBar />
<RouterView />
</template>
My paths:
- "/"
- "/faq"
- "counter/x" => here i need the badge in the navbar
- "counter/y" => here i need the badge in the navbar
I also use a simple store solution. Here I have a function
export const store = reactive({
isCounterPage: false,
checkIsCounterPage() {
this.isCounterPage = window.location.pathname.includes("/counter/");
}
}
In the router/index.js File, I call the checkIsCounterPage()
method.
// router/index.js
router.beforeEach(async (to, from, next) => {
store.checkIsCounterPage()
}
And in my navbar, I use a condition where i check the variable:
// someView.vue
<template>
<div v-if="store.isCounterPage" >BADGE</div>
</template>
Unfortunately, it doesn't work the way I want it to. Only after a hard refresh of the page (for example F5 / refresh Page) it recognises where it is. So the problem is that the store method is only called once on initialisation and not on route change as I assume.
Question:
What am I doing wrong and is this the right way at all?
CodePudding user response:
You can add meta field to your counter routes:
routes: [
{ path: '/counter/x', component: x, meta: { isCounterPage: true } },
...
],
and check meta:
router.beforeEach(async (to, from, next) => {
if (to.meta.isCounterPage) store.checkIsCounterPage(true)
next()
}
and in store:
export const store = reactive({
isCounterPage: false,
checkIsCounterPage(val = false) {
this.isCounterPage = val
}
}
CodePudding user response:
what about watching to route changes in the navbar component. for example;
with composition api
const route = useRoute()
const badgeDisplay = ref(false)
watch(route.path, (val) => {
if (val === x) badgeDisplay.value = true
else badgeDisplay.value = false
})
options api
watch: {
$route (to, from) {
if (to === x) this.badgeDisplay = true
else this.badgeDisplay = false
}
}