Layouting in Vue is nothing but another use of reusable components. Different pages require different elements (UI), such as navigation, menu etc. Some of them are repeated in each page, like router links / page links.
We can create layout for such components and wrap child with the layout. Can I apply it at the router level ?. A dynamic layout / router level layout will serve the needs.
Dynamic AppLayout
The concept is not new, create layout constructor and apply layout based on the route change. First up all create folder named layouts and Applayout.vue file.
This example uses Vue 3 setup
<template> <component :is="layout"> <slot /> </component> </template> <script> import AppLayoutDefault from './AppLayoutDefault' export default { name: "AppLayout", data: () => ({ layout: AppLayoutDefault }), watch: { $route: { immediate: true, async handler(route) { try { const component = await import(`@/layouts/${route.meta.layout}.vue`) this.layout = component?.default || AppLayoutDefault } catch (e) { this.layout = AppLayoutDefault } } } } } </script>
This is a wrapping component which will check the route meta layout and apply dynamically. We can use this component at App.vue as follows.
<template> <div id="app"> <AppLayout> <router-view /> </AppLayout> </div> </template> <script> import AppLayout from './layouts/AppLayout' export default { name: 'App', components: { AppLayout } } </script>
Default Layout
We need a blank layout in case no layout is specified. In our layouts folder create AppLayoutDefault.vue with simple slot.
<template> <div> <slot /> </div> </template>
Other layouts
Let's focus on Home layout AppLayoutHome.vue,
<template> <div> <header class="header" >Home Layout</header> <slot /> </div> </template> <script> export default { name: "AppLayoutHome", } </script>
You can also create a LinkLayout for router Links too, I skipped it for simplicity.
Now our Layouting almost ready with two layout, a final configuration is required to work this setup.
Applying Layouts
In the router/index..vue locatte the router configuration and add out meta layout property as follows
{ path: '/', name: 'Home', component: Home, meta:{ layout:'AppLayoutHome' }
That's it we are not ready to go.
The complete source code of the project can be found at Vue3 Repo
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.