vite-plugin-vue-layouts icon indicating copy to clipboard operation
vite-plugin-vue-layouts copied to clipboard

Children inheriting meta fields from layouts

Open Sensanaty opened this issue 2 years ago • 3 comments

Is there a way to have the child pages of a layout (aka the pages actually utilizing the layout) inherit the meta fields of the layout?

Say for example I create an authenticated.vue layout that is only accessible if a token is present. The actual navigation guard logic is easily handled by vue router middleware, but I'd like to have the auth: true meta field present in the main authenticated.vue layout, with all pages utilizing it inheriting that (instead of having to set auth: true on each page). Is that possible? The way I tried to do it, it doesn't seem like the page gets the layout's meta properties.

This is what I tried:

// layouts/authenticated.vue
<route lang="yaml">
meta:
  auth: true
</route>

// pages/dashboard.vue
<route lang="yaml">
meta:
  layout: admin
</route>

Sensanaty avatar Jul 04 '22 00:07 Sensanaty

如果你使用了vite-plugin-pages,我想这个可以解决你的问题,而不是这个库

itmanyong avatar Aug 06 '22 10:08 itmanyong

image image

zhuhaobam avatar Aug 08 '22 08:08 zhuhaobam

This is my project. See if this is the nested layout you need. In addition, if you need to change the layout after authorization, you may need to refresh the route https://github.com/zhuhaobam/vtdd

zhuhaobam avatar Aug 08 '22 09:08 zhuhaobam

After half a day of reading/inspecting the source codes here and there, I finally figured out a way around it. This is how I worked around this issue. the idea is pretty simple: since the final generated routes will have the layouts on the top level, we can inject the meta here by defining all required meta here instead of defining it inside each layout. I hope this helps until the author of the package fixes it.

// router/index.ts

import type { RouteRecordRaw } from 'vue-router'

const metasByLayout: {[key: string]: object} = {
  default: {
    auth: true,
  },
}
export function generateLayoutsMeta(routes: RouteRecordRaw[]):RouteRecordRaw[] {
  return routes.map (route => {
    const layoutName: string = route.children?.[0]?.meta?.layout as string || 'default'
    const meta: object = metasByLayout[layoutName] as object
    return {...route, meta} as RouteRecordRaw
  })
}

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    ...generateLayoutsMeta(setupLayouts(routes)),
  ],
})

RoduanKD avatar Mar 16 '23 13:03 RoduanKD

I'd take a PR for this, but it's not something I'm going to add.

JohnCampionJr avatar Dec 05 '23 02:12 JohnCampionJr