Cannot use string variable for <component :is="someVar"> with script-setup
Version
3.2.8
Reproduction link
Steps to reproduce
See link to repro.
What is expected?
The HelloWorld component should be shown.
What is actually happening?
The HelloWorld component is not shown. No console error.
This doesn't work:
<template>
<component :is="myComponent"></component>
</template>
<script setup>
import HelloWorld from './HelloWorld.vue'
const myComponent = 'HelloWorld'
</script>
Passing the object instead of the string works:
<script setup>
import HelloWorld from './HelloWorld.vue'
const myComponent = HelloWorld // Removed the quotes
</script>
But I'd expect the first snippet to work since it's possible to pass it as string in the following example
<script>
import HelloWorld from './HelloWorld.vue'
export default {
components: {
HelloWorld
},
setup() {
const myComponent = 'HelloWorld'
return {
myComponent
}
}
}
</script>
It is expected. Without the components
option you don't have a chance to give the component a local name (string) and there's no need to do so.
and there's no need to do so.
@Justineo This was a contrived example, but my actual use case is a dynamically generated form. I have a list of async components:
// ComponentsList.js:
import { defineAsyncComponent } from 'vue'
export default {
CheckBox: defineAsyncComponent(() => import('./CheckBox.vue')),
TextBox: defineAsyncComponent(() => import('./TextBox.vue')),
...
}
And generate the form using code similar to this:
<template>
<component
v-for="component in myListOfDesiredComponents"
:key="component.controlId"
:is="'Components.' + component.type"
v-bind="component.model"
></component>
</template>
<script setup>
import Components from './ComponentsList.js'
const props = defineProps({
myListOfDesiredComponents: Array // Example of item: { type: 'CheckBox', controlId: 'something-unique', model: { name: 'Foo' } }
})
</script>
The string being 'CheckBox' in this example. Indeed it works when using the components: Components
option, but is there no way to make this work with script-setup?
@leboeuf I solved it by creating a map that goes from strings to the imported components.
import HelloWorld from './components/HelloWorld.vue'
import FooComp from './layouts/FooComp.vue'
export const compMap = new Map()
compMap.set("HelloWorld", HelloWorld)
compMap.set("FooComp", FooComp)
then you can use that and get the value instead of using it directly