So I'm trying to achieve a layout with optional sidebars based on the vue routes
Currently I have the following:
- an
App.vue
which has aMainLayout
component with slots where I'm placing the router views
<main-layout>
<template #main>
<router-view/>
</template>
<template #sidebar>
<router-view name="LeftSidebar"/>
</template>
<template #rightsidebar>
<router-view name="RightSidebar"/>
</template>
</main-layout>
- the router looking something like this:
const routes = [
{
path: "/lectures",
components: {
default: LectureList,
LeftSidebar: MainMenu,
}
},
{
path: "/users",
components: {
default: UserList,
LeftSidebar: MainMenu,
RightSidebar: SomeOtherComponent
}
},
]
- the
MainLayout.vue
looking something like this (simplified)
<div>
<div >
<slot name="sidebar"/>
</div>
<div >
<slot/>
</div>
<div >
<slot name="rightsidebar"/>
</div>
</div>
Currently the main menu layout has a slot for the rightsidebar
and I'd like it to render only if it has some content, ie if some route provides a component for the RightSidebar
router view. I tried looking at the slots
in MainLayout
and add a v-if
on the .right-sidebar
div to only show if the slot for rightsidebar
slot is present, but I guess it doesn't work since the router-view
is present in there already
Any recommended way of dealing with this type of case?
CodePudding user response:
Using the matched
property of the Vue router named views, we can check which props have been passed or not.
Here in the code, I added a watcher which will check for every route if props for sidebar views are passed or not and will update the data properties to used as the conditions.
<main-layout>
<template #main>
<router-view/>
</template>
<template #sidebar v-if="isLeftSideBar">
<router-view name="LeftSidebar"/>
</template>
<template #rightsidebar v-if="isRightSideBar">
<router-view name="RightSidebar"/>
</template>
</main-layout>
<script >
export default {
name: "App",
data() {
return {
isLeftSideBar: false,
isRightSideBar: false
}
},
watch: {
$route(to, from) {
if (to.matched.length) {
this.isLeftSideBar = to.matched[0].props.hasOwnProperty("LeftSidebar");
this.isRightSideBar = to.matched[0].props.hasOwnProperty("RightSidebar");;
}
}
},
}
</script>
Please let me know if this works.