Often I find that I'm copying prop types from a child component, just to use them in a parent component. But I've discovered that stealing those prop types is much better than just copying them.
For example, we have an Icon
component being used in this component:
<template><div><h2>{{ heading }}</h2><Icon:type="iconType":size="iconSize":colour="iconColour"/></div></template>
To get this to work, we need to add the correct prop types, copying from the Icon
component:
import Icon from './Icon';export default {components: { Icon },props: {iconType: {type: String,required: true,},iconSize: {type: String,default: 'medium',validator: size => ['small','medium','large','x-large'].includes(size),},iconColour: {type: String,default: 'black',},heading: {type: String,required: true,},},};
(I've previously written about how to use the validator pattern and other tricks with prop types.)
What a pain.
And when the prop types of the Icon
component are updated, you can be sure that you'll forget to come back to this component and update them. Over time bugs will be introduced as the prop types for this component start to drift away from the prop types in the Icon
component.
So that's why we'll steal them instead:
import Icon from './Icon';export default {components: { Icon },props: {...Icon.props,heading: {type: String,required: true,},},};
It doesn't have to get any more complicated than that!
Except in our example, we have "icon" added to the beginning of each prop name. So we'll have to do some extra work to get that to happen:
import Icon from './Icon';const iconProps = {};// Do some processing beforehandObject.entries(Icon.props).forEach((key, val) => {iconProps[`icon${key[0].toUpperCase()}${key.substring(1)}`] = val;});export default {components: { Icon },props: {...iconProps,heading: {type: String,required: true,},},};
Now, if the prop types in the Icon
component are modified, our component will stay up-to-date.