Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue 3: implement dynamic layout rendering with composition api correctly

I'm trying to implement a good way to generate dynamic layout components that change according to my route meta settings (if the route has meta: { layout: 'LayoutName' } it should load that layout instead, otherwise it loads the default one MainLayout.vue).

After lot of try and error I managed to get it working:

// My main App.vue file
<template>
    <component :is="layout">
        <router-view />
    </component>
</template>

<script setup>

import { defineAsyncComponent, computed } from 'vue'
import { useRoute } from 'vue-router';

let layout = computed( () => { 
        const { meta } = useRoute()
        return defineAsyncComponent( () => import(`./layouts/${meta.layout ?? 'MainLayout'}.vue`) )
    }
)

My question is: is this way of mixing computed and defineAsyncComponent advisable?

I tried to use either watch and watchEffect but didn't get to accomplish a working result. Do you have any suggestions?

like image 638
Santiago Avatar asked Nov 23 '25 20:11

Santiago


1 Answers

Bro, computed won't work for you since webpack import can't compute meta.layout ?? and make an import. To fix this, make a separate variable for layout. Something like that:

layout(): ILayout {
  const { meta } = useRoute();
  const layoutName: TLayout = meta.layout ?? 'DefaultLayout';
  return defineAsyncComponent(
    () =>
      import(/* webpackChunkName: 'Layout' */ `@/layouts/${layoutName}.vue`)
  );
}

P.S. Never mind the syntax. I am using typescript.

like image 51
blurryfacebeat Avatar answered Nov 25 '25 10:11

blurryfacebeat