Home > other >  Dynamic Routing for Dynamic Components in Vue3
Dynamic Routing for Dynamic Components in Vue3

Time:07-14

Dynamic component with Dynamic Routing is needed for me in Vue3. I wanted to render the component which is coming from the params (path named id) from the router.ts

As you can see here in router.ts I have a dynamic parameter named as id. I wanted the same component have to be rendered with the same name.

For example: If http://localhost:3000/semanux/form/FirstPage is entered it should rended the FirstPage component which I had already created in my project.

and when http://localhost:3000/semanux/form/SecondPage is entered it should rendered the SecondPage componet and so on...

My question is how to do it I have tried multiple ways and one of the way is like that:

  {
    path: "/semanux/form/:id",
    component: () => import("../pages/"   location.pathname.slice(1)   ".vue")
  },

But it is not working. Below I have also shared my App.vue and router/index.ts code

  1. This is my router/index.ts file
import { createWebHistory, createRouter, useRoute } from "vue-router"
import FirstPage from "../pages/FirstPage.vue"
import SecondPage from "../pages/SecondPage.vue"
import ThirdPage from "../pages/ThirdPage.vue"
import NotFound from "../components/NotFound.vue"
const routes = [
  {
    path: "/",
    name: "first",
    component: FirstPage
  },
  {
    path: "/2/70",
    name: "second",
    component: SecondPage
  },
  {
    path: "/3/70",
    name: "third",
    component: ThirdPage
  },
  {
    path: "/semanux/form/:id",
    component: () => import("../pages/"   location.pathname.slice(1)   ".vue")
  },
  {
    path: "/:catchAll(.*)",
    component: NotFound
  }
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

export default router

  1. App.vue file

<template>
  <router-view></router-view>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>router/index.ts file

CodePudding user response:

location.pathname isn't generally supposed to be accessed directly in Vue router. It shouldn't be accessed at the point when route component is resolved because the location isn't changed yet.

Dynamic component can be wrapped with another component:

  {
    path: "/semanux/form/:id",
    component: FormWrapperPage,
  },

Where wrapper component is something like:

<component :is="PageComp"/>

...

const route = useRoute();
const PageComp = ref();

watch(
  () => route.params.id,
  async id => {
    try {
      PageComp.value = (await import("../pages/"   id   ".vue")).default
    } catch {
       router.push('/404')
    }
  },
  { immediate: true }
)

Since dynamic component is rendered after navigation, missing components need to be handled manually.

  • Related