In this post I will show you'll how to work with component props in Vue 3 + Composition API using <script setup>
, there's few ways to work with it, let's take a look!
Using the defineProps() macro we can declare props like:
1 - Array of strings
<script setup>
const props = defineProps(['foo'])
console.log(props.foo)
</script>
2 - Object syntax
<script setup>
const props = defineProps({
title: String,
likes: Number
})
console.log(props.title)
</script>
2.1 - Object syntax with details
<script setup>
const props = defineProps({
title: {
type: String,
required: true,
default: '---'
},
})
</script>
Working with props in Vue 3 with Typescript
Let's see how to declare props in Vue 3 script setup with Typescript:
1 - Type-based declaration
<script setup lang="ts">
defineProps<{
title?: string
likes: number
}>()
</script>
In this case we have title and likes props, title is optional and likes is an required prop.
2 - Type-based declaration with default props values
<script setup lang="ts">
withDefaults(defineProps<{
title?: string
likes: number,
}>(), {
// here we have default values
title: '---',
})
</script>
3 - Advanced types with PropType
For use PropType interface you need to import it from vue:
<script setup lang="ts">
import { type PropType } from 'vue'
export interface Book {
title: string
author: string
year: number
}
const props = defineProps({
book: {
type: Object as PropType<Book>,
required: true,
}
})
</script>
That's it!
If you want to read and learn more details about component props declaration, please make sure to visit the Vue 3 official documentation about props.
See'ya!
Top comments (8)
Being a big fan of script setup approach, I find your example useful.
However, since you are using Typescript, I would suggest you change the approach a bit.
This would, from my perspective be a more readable, maintainable, and less bloated if you actually embrace the power of Generics in Typescript.
My approach from your example would be:
If you want a prop to be optional:
And with default props:
Usually I would name my prop interface to mirror the component I use it in:
The above examples does the exact same thing as it does in your examples, but we do not have to define type and required for each field in the props, since that is being handled perfectly by Typescript and Vue
Nice, can you also give an example of how to do this when you have a validator for a prop? I can't figure out how to do this with this syntax...
If you try to give me an example for custom validator you would use for a prop, I'll show you how I would do it.
Amazing approach, Dennis!
I'll make sure to follow this way of work with props and typescript for now, much more readable and maintainable.
Thanks for the contribuition!
Thankyou for the idea
Thanks!!! This post is really helpful :)
Thanks for the post, is very helpful
You're welcome! Thanks :)