Reputation: 223104
There is properly typed BaseComp
base component, which can be a third-party component and so can't be rewritten to suit our needs:
<script lang="ts">
...
export default defineComponent({
name: 'BaseComp',
props: {
baseProp: {
type: String,
},
anotherBaseProp: {
type: String,
},
},
...
});
</script>
And MyComp
wrapper component:
<template>
<BaseComp
v-bind="$attrs"
:base-prop="myBaseProp"
:another-base-prop="someProp"
/>
</template>
<script lang="ts">
...
export default defineComponent({
name: 'MyComp',
components: { BaseComp },
props: {
baseProp: {
type: String,
},
someProp: {
type: String,
},
},
setup(props) {
const myBaseProp = computed(() => transform(props.baseProp));
return { myBaseProp };
},
});
</script>
MyComp
is expected to have the same prop types as BaseComp
in TypeScript, plus someProp
- both internally (props
inside setup
function) and externally (templates and render functions).
The use of $attrs
works as it should at runtime but MyComp
won't get unlisted prop types from BaseComp
at compilation time (anotherBaseProp
).
MyComp
doesn't use extends
as it doesn't inherit all component options, just props.
What is the proper way to make MyComp
expose the correct props?
Can it allow to not list common props a wrapper that it explicitly uses (someProp
)?
Upvotes: 1
Views: 2060
Reputation: 6919
In Vue3, you have two ways to do this: with mixins
or composition api
. The composition api being the recommended way to do as stated in the Vue 3 documentation.
Officially, you can't extends only some parts of another components without extending it entirely.
EDIT: There is a solution that is not documentation and may be breakpoint for various reasons.
If possible, I do not recommend to use this method unless it has been officially documented somehow.
import BaseComp from 'BaseComp.vue'
export default defineComponent({
name: 'MyComp',
components: { BaseComp },
props: {
...BaseComp.props, // Object containing BaseComp props object
},
});
Export a function with the common props definition.
export const useGlobalProps = () => {
return {
baseProp: {
type: String,
},
someProp: {
type: String,
},
},
}
defineComponent
methodimport { useGlobalProps } from 'globalProps'
export default defineComponent({
name: 'BaseComp',
props: {
...useGlobalProps(),
otherProp: Boolean,
}
...
});
script setup
model<script setup>
import { useGlobalProps } from 'globalProps'
defineProps({
...useGlobalProps(),
otherProps: Boolean,
})
</script>
// base-mixin.js
export default {
props: {
baseProp: {
type: String,
},
someProp: {
type: String,
},
},
}
import BaseMixin from 'base-mixin'
export default defineComponent({
name: 'BaseComp',
mixins: [BaseMixin],
...
});
export default defineComponent({
name: 'MyComp',
mixins: [BaseMixin],
...
});
Upvotes: 1