I've recently switched from Vue2
to Vue3
but I'm sort of confused to what the best practice is to shared props
between multiple components. I want to make input components which share the common props
like "type", "name", etc. Previously I did it with mixins
but I wonder if this still is the best way to do so.
Let me give an exampleof what I tried via the options-api
:
// Home.vue
<template>
<p>Home</p>
<p>{{ type }}</p>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { sharedInputProps } from '../admin/composables/sharedInputProps'
export default defineComponent({
props: {
...sharedInputProps,
},
setup() {
return {
}
},
})
</script>
// sharedInputProps.ts
import { ComponentPropsOptions } from 'vue'
export const sharedInputProps: ComponentPropsOptions = {
type: {
type: String,
required: true,
default: 'text',
}
}
This works but I get no typehinting/autocompletion in my IDE to what the props are in Home.vue
(in this case <p>{{ type }}</p>
.
This is how I would do it with mixins:
// Home.vue
<template>
<p>Home</p>
<p>{{ type }}</p>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import InputProps from '../admin/mixins/InputProps.vue'
export default defineComponent({
mixins:[
InputProps,
],
setup() {
return {
}
},
})
</script>
// InputProps.vue
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
props: {
type: {
type: String,
required: true,
default: 'text',
}
},
})
</script>
This works as intended and it gives me proper typehinting/autocompletion.
But I wonder how this should be done with the composition-api
using the defineProps
method. I got it to work directly defining the props in Home.vue
with typehinting/autocompletion, as shown below:
// Home.vue
<template>
<p>Home</p>
<p>{{ type }}</p>
</template>
<script setup lang="ts">
import { defineProps, withDefaults } from 'vue'
interface Props {
type?: string
}
const props = withDefaults(defineProps<Props>(), {
type: 'text',
})
</script>
But as the documentation (https://vuejs.org/guide/typescript/composition-api.html#typing-component-props) states, it cannot be loaded from an external file.
So my question is, since using an external file with the composition-api
is not supported (yet?) and an external file using the options-api
and using the spread
operator to destructurize an object is not giving typehinting/autocompletion, is mixins
still the best practice to share props? Or am I misconfiguring something in my sharedProps.ts
file (or somewhere else)?
I'm running the latest version of Vue 3(3.2.47
) and I'm using the latest version of PHPStorm(2023.1
) as my IDE.
ComponentPropsOptions
type prevents sharedInputProps
to be implicitly typed.
If sharedInputProps
are supposed to be compatible with ComponentPropsOptions
type, it's possible do use satisfies
in TypeScript 4.9 or higher:
export const sharedInputProps = {
type: {
type: String,
required: true,
default: 'text',
}
} satisfies ComponentPropsOptions
This keeps the correct type when it's used as props: { ...sharedInputProps }
and allows to spot an error in place where it's defined if it's incorrect.