I have a component that collects data from an API. The data returned from the API is an array containing the details. One of the values in the array is the type of component that should be rendered, all other data is passed to the component. I'm trying to render the correct component based on the value brought back from the database, but unfortunately it doesn't work. I'm new to Vue but it works in vue2 but hope it works in Vue 3 using composition API.
This is the component code I want to replace:
<component :is="question.type" :propdata="question" />
When viewed in a browser, this is what is actually displayed, but without using the SelectInput component:
<selectinput :propdata="question"></selectinput>
SelectInput is a component of my directory and if I hardcode the :is
value it works as expected like this:
<component :is="SelectInput" propdata="question" />
My complete component calls the component
component and swaps components:
<template> <div class="item-group section-wrap"> <div v-bind:key="question.guid" class='component-wrap'> <div class="component-container"> <!-- working --> <component :is="SelectInput" :propData="question" /> <!-- not working --> <component v-bind:is="question.type" :propData="question" /> </div> </div> </div> </template> <script setup> import { defineProps, toRefs } from 'vue'; import SelectInput from "./SelectInput"; import TextareaInput from "./TextareaInput"; const props = defineProps({ question: Object, }); const { question } = toRefs(props); </script>
P粉3889454322024-02-26 13:55:24
If your component filenames equal the type specifiers on the object in question, then you can dynamically import them to save some lines of code.
This also leads to better scalability because if you create more types, you don't have to touch this component anymore.
P粉7757887232024-02-26 13:00:49
Found that because I was using a script setting
, the component was not named, so the component
component didn't know which component to render.
So I create an object containing the component and a reference to the component:
const components = { 'SelectInput': SelectInput, 'TextareaInput': TextareaInput };
Another function that takes the component I want to display and links it to the actual component:
const component_type = (type) => components[type];
Then in the template I call the function and render the correct component:
Complete fixed code:
Not quite sure if this is the correct approach, but it renders the correct component now.