Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading different components based on route param in Vue Router

I'm building an editor app which supports multiple design templates. Each design template has wildly different set of fields so they each has their own .vue file.

I'm trying to dynamically load the corresponding view component file based on params. So visiting /editor/yellow-on-black would load views/designs/yellow-on-black.vue etc.

I've been trying to do it like this

{
  path: '/editor/:design',
  component: () => {
    return import(`../views/designs/${route.params.design}`)
  }
}

But of course route is not defined. Any idea on how to work around this?

like image 346
starleaf1 Avatar asked Oct 20 '25 22:10

starleaf1


1 Answers

The route's component option is only evaluated once, so that won't work. Here's a solution using a Dynamic.vue view which uses a dynamic component based on the route param.

Use a simple route definition with route param. I changed the param name to dynamic:

import Dynamic from '@/views/Dynamic.vue';

{
  path: "/editor/:dynamic",
  component: Dynamic
}

Create a generic Dynamic.vue component that dynamically loads a component from the route param. It expects the param to be called dynamic:

<template>
  <component v-if="c" :is="c" :key="c.__file"></component>
</template>
<script>
export default {
  data: () => ({
    c: null
  }),
  methods: {
    updateComponent(param) {
      // The dynamic import
      import(`@/components/${param}.vue`).then(module => {
        this.c = module.default;
      })
    }
  },
  beforeRouteEnter(to, from, next) {
    // When first entering the route
    next(vm => vm.updateComponent(to.params.dynamic));
  },
  beforeRouteUpdate(to, from, next) {
    // When changing from one dynamic route to another
    this.updateComponent(to.params.dynamic);
    next();
  }
}
</script>
like image 148
Dan Avatar answered Oct 23 '25 21:10

Dan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!