So I'm looking at wrapping some Vuetify
components into my own custom component so I can more finely control the look and feel throughout our application. The issue that I'm running into is that I want to have 'default' props for the Vuetify
component, and that works fine, BUT when I also add props when consuming the component, these are 'override' props are not being used.
Vue 3.2.38, Vuetify 3.1.10
Custom Component:
<template>
<label v-if="name">{{ name }}</label>
<v-text-field v-bind="{ ...$attrs, ...$props, ...defaultProps }">
<template v-for="(_, scopedSlotName) in $slots" #[scopedSlotName]="slotData">
<slot :name="scopedSlotName" v-bind="slotData" />
</template>
<template v-for="(_, slotName) in $slots" #[slotName]>
<slot :name="slotName" />
</template>
</v-text-field>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { VTextField } from 'vuetify/components/VTextField';
export default defineComponent({
name: 'EmailField',
extends: VTextField,
props: {
name: {
type: String,
default: ''
}
},
computed: {
defaultProps() {
return {
color: 'yellow',
bgColor: '#252836',
variant: 'outlined',
density: 'compact'
};
}
}
});
</script>
Consuming the component:
<template>
.......other template items
<EQEmailField v-model="email" name="Email Address" counter :persistentCounter="true" color="blue" density="comfortable" />
</template>
<script lang="ts">
import { defineComponent, defineAsyncComponent } from 'vue';
export default defineComponent({
components: {
EmailField: defineAsyncComponent(() => import('@/components/custom/email-text-field.vue'))
}
});
</script>
So the default props(defaultProps) that I set in the component work fine and apply to Vuetify correctly. The issues arise when consuming the component and I pass props to override the default components props. They default props are always used and the passed in props on the consumer side are not being used. If I try to override a value that's in my defaultProps object then it doesn't work. If I use a prop that I don't already have set in defaultProps then it works fine. So I'm guessing I need a way to parse through the props and determine which one to actually apply? I realize this may be a tough thing to do but seems like this would be a somewhat common occurrence.
Just define them as props with default values that you've listed in computed proeprty :
export default defineComponent({
name: 'EmailField',
extends: VTextField,
props: {
name: {
type: String,
default: ''
},
color:{
type:String,
default:'yellow'
},
//the same process for other props
},
});
then in template :
<v-text-field v-bind="{ ...$attrs, ...$props}">