skip to Main Content

I try to use dynamic component to update my section.
But, when i click on my sidebar (‘nav’), it dont change.
route.params.current change, but component is not loaded.


<template>
  <q-page class="container q-py-lg">
    <div class="q-pa-md row q-gutter-md">
      
      <nav class="col">
        <ul>
          <li v-for="(link, i) in links" :key="i" :class="link.label === route.params.current ? 'active' : 'cursor-pointer'" @click="router.push({ name: 'settings', params: { current: link.label }})">
            <span><q-icon size="xs" class="icon q-mx-sm" :name="link.icon"></q-icon></span>
            <span>{{  t(link.label) }}</span>
          </li>
        </ul>
      </nav>

      <section class="col-xs-12 col-md-6 col-lg-9">
        <q-card flat class="bg-teal text-white">
          <q-card-section>
            <component :is="getComponent(route.params.current)"></component>
          </q-card-section>
        </q-card>
      </section>
    </div>
  </q-page>
</template>

<script setup>
import { useI18n } from "vue-i18n";
import { useRoute, useRouter } from "vue-router";

const { t } = useI18n();
const route = useRoute();
const router = useRouter();

const getComponent = (name) => import(`./Settings/${name}.vue`);

const links = [
  { label: "account", icon: "person" },
  { label: "gameBehavior", icon: "sports_esports" }
];

</script>

2

Answers


  1. <Component :is="getComponent"></Component>
    <script setup>
    import {ref, defineAsyncComponent} from 'vue'
    const name =ref(null)  // if you use it - define it
    const getComponent =computed(()=> 
             defineAsyncComponent(()=>import(`./Settings/${name.value}.vue`)
    </script>
    
    Login or Signup to reply.
  2. You can create a watcher for the route and on the callback function you can assign your dynamicComponent by passing any component name. In my case, I am watching for route.name (you can use any, as it is a basic example).

    But the trick here is to wait for the component to load as it is an asynchronous import. That’s how you can get the component easily.

    Also use shallowRef instead of ref when you define dynamicComponent. shallowRef will ensure that the component itself is not made reactive, only the reference to it.

    Learn more about DynamicComponents here

    <template>
      <header>
        <nav>
          <RouterLink to="/">Home</RouterLink>
          <RouterLink to="/about">About</RouterLink>
        </nav>
      </header>
    
      <!-- Pass the dynamicComponent variable as component -->
      <component :is="dynamicComponent"></component>
    </template>
    
    <script lang="ts" setup>
    import { RouterLink } from 'vue-router'
    import { shallowRef, watch } from "vue";
    import { useRoute } from "vue-router";
    
    const route = useRoute();
    
    // Use shallowRef instead of ref when you define dynamicComponent.
    // shallowRef will ensure that the component itself is not made reactive,
    // only the reference to it.
    const dynamicComponent = shallowRef<any>(null);
    
    // Watch for the change in the route name in the router
    // You can watch any property
    watch(route, async () => {
      dynamicComponent.value = (await import(`./views/${route.name as string}View.vue`)).default;
    });
    </script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search