0
votes

I am trying to have render different components based on the route query produced by clicking tabs. I have tried a dynamic component approach but it is working only on initial load. When I switch by clicking tabs which changes the route query it does not change to the other component. Below are my code and files

Show.vue

<div>
    <b-container fluid class="bg-white">
        <b-row class="topTab types" v-if="$refs.chart">
          <b-col
            :class="{ active: currentTab === index }"
            v-for="(tabDisplay, index) in $refs.chart.tabDisplays"
            :key="index"
          >
            <router-link
              :to="{ query: { period: $route.query.period, tab: index } }"
            >
              {{ tabDisplay }}
            </router-link>
          </b-col>
        </b-row>
      </b-container>
      <component v-bind:is="currentExample" ref="chart" />
</div>

export default {
    props: {
      group: String,
      cp: String,
      name: String,
      id: [Number, String]
    },
    computed: {
      currentExample() {
        return () =>
          import(
            `@/components/Trend/example/Charts/${this.group}/${this.id}/Base.vue`
          );
      },
    }
}

Below is the component used above snippet

Base.vue

<template>
  <component v-bind:is="currentData"> </component>
</template>

<script>
export default {
  data: function() {
    return {
      tabDisplays: {
        1: "example1",
        2: "example2",
        3: "example3",
        4: "example4",
        5: "example5",
        6: "example6"
      }
    };
  },
  computed: {
    currentData() {
      return () =>
        import(
          `@/components/Trend/example/Charts/${this.$route.params.group}/${
            this.$route.params.id
          }/Tab${this.$route.query.tab === "6" ? "6" : "1-5"}.vue`
        );
    }
  }
};
</script>

I am expecting that if I click the example6 link. It will show my @/components/Trend/example/Charts/${this.group}/${this.id}/Tab6.vue on the <component>

2

2 Answers

0
votes

Dynamic components :is expects and identifier not a fully fledged component.

You should import the component under the components property in your parent component and then use the computed property to only get the identifier.

components: {
    'comp{group}{id}{tab}': () => import(
          `@/components/Trend/example/Charts/{group}/{id}/Tab{tab}.vue`)
}

Note: {group}, {id} and {tab} are only placeholders for your actual values. You need to import all of them.

And use the currentData to only get the identifier:

computed: {
  currentData() {
   return `comp${this.$route.params.group}${this.$route.params.id}{this.$route.query.tab === "6" ? "6" : "1-5"}`
  }
}
0
votes

I have fixed it by just being a simple.

Base.vue

<template>
  <component v-bind:is="currentData"> </component>
</template>

<script>
import Tab from "@/components/Trend/example/Charts/abc/1/Tab1-5.vue";
import Tab6 from "@/components/Trend/example/Charts/abc/1/Tab6.vue";

export default {
  computed: {
    currentData() {
      if (this.$route.query.tab === "6") {
        return Tab6;
      } else {
        return Tab;
      }
    }
  }
};
</script>

My structure allows me to be simple and straightforward on this level