admin管理员组

文章数量:1334292

I have a process which have many steps. Each one is implemented in a different component.

Initially I had this code:

<template>
  <template v-if="process.currentStep === 0">
    <Step0 />
  </template>
  <template v-else-if="process.currentStep === 1">
    <Step1 />
  </template>
  <template v-else-if="process.currentStep === 2">
    <Step2 />
      :
      :
</template>

<script setup>
import Step0 from "@/views/components/steps/step0.vue";
import Step1 from "@/views/components/steps/step1.vue";
import Step2 from "@/views/components/steps/step2.vue";
  :
  :

However, in order to make the code more readable, I tried to change to:

<template>
  <component :is="`Step${process.currentStep}`" />

But it doesn't work.

I also tried:

<component :is="stepComponent" />

import { defineAsyncComponent } from 'vue';

const stepComponent = ref(); // Adjust the initial value as needed
const stepComponents = {
  Step0: defineAsyncComponent(() => import('@/views/components/steps/step0.vue')),
  Step1: defineAsyncComponent(() => import('@/views/components/steps/step1.vue')),
  Step2: defineAsyncComponent(() => import('@/views/components/steps/step2.vue')),
};

But neither get any result.

I don't want to register these components in main.ts. Is there any way to do what I am trying to do?

I have a process which have many steps. Each one is implemented in a different component.

Initially I had this code:

<template>
  <template v-if="process.currentStep === 0">
    <Step0 />
  </template>
  <template v-else-if="process.currentStep === 1">
    <Step1 />
  </template>
  <template v-else-if="process.currentStep === 2">
    <Step2 />
      :
      :
</template>

<script setup>
import Step0 from "@/views/components/steps/step0.vue";
import Step1 from "@/views/components/steps/step1.vue";
import Step2 from "@/views/components/steps/step2.vue";
  :
  :

However, in order to make the code more readable, I tried to change to:

<template>
  <component :is="`Step${process.currentStep}`" />

But it doesn't work.

I also tried:

<component :is="stepComponent" />

import { defineAsyncComponent } from 'vue';

const stepComponent = ref(); // Adjust the initial value as needed
const stepComponents = {
  Step0: defineAsyncComponent(() => import('@/views/components/steps/step0.vue')),
  Step1: defineAsyncComponent(() => import('@/views/components/steps/step1.vue')),
  Step2: defineAsyncComponent(() => import('@/views/components/steps/step2.vue')),
};

But neither get any result.

I don't want to register these components in main.ts. Is there any way to do what I am trying to do?

Share Improve this question edited Nov 20, 2024 at 20:23 isherwood 61.1k16 gold badges121 silver badges169 bronze badges asked Nov 20, 2024 at 20:06 guyaloniguyaloni 5,9325 gold badges59 silver badges104 bronze badges 1
  • 1 Please don't tag your title question. See How to Ask. – isherwood Commented Nov 20, 2024 at 20:23
Add a comment  | 

2 Answers 2

Reset to default 3

is value should be component object itself, it won't resolve a string like :is="'Step0'" to a component automatically.

It is:

<script setup>
import Step0 from "@/views/components/steps/step0.vue";
...
const stepComponents = { Step0, ... }
...
<component :is="stepComponents[`Step${currentStep}`]"

Step0, etc can be defineAsyncComponent for lazy loading, but this is not necessary.

You need to use a computed properties which will act as component loader

<template>
  <!-- Dynamically load the component based on the current step -->
  <component :is="componentLoader" />
</template>

<script setup>
import { defineAsyncComponent, computed } from 'vue';

// Define async components for each step
const stepComponents = {
  Step0: defineAsyncComponent(() => import('@/views/components/steps/step0.vue')),
  Step1: defineAsyncComponent(() => import('@/views/components/steps/step1.vue')),
  Step2: defineAsyncComponent(() => import('@/views/components/steps/step2.vue')),
};

// replace with your real process object
const process = reactive({
  currentStep: 0,
});

// Compute the current component based on the current step
const componentLoader = computed(() => {
  const stepKey = `Step${process.currentStep}`;
  return stepComponents[stepKey] || null; // Return null if the step is not found
});
</script>

本文标签: javascriptHow can I render components dynamically with Vue 3Stack Overflow