|
18 | 18 | - [Native Types](#native-types)
|
19 | 19 | - [Native Types Configuration](#native-types-configuration)
|
20 | 20 | - [Custom Types](#custom-types)
|
| 21 | + - [Extending VueTypes](#extending-vuetypes) |
21 | 22 | - [Utilities](#utilities)
|
22 | 23 | - [License](#license)
|
23 | 24 |
|
@@ -252,6 +253,25 @@ VueTypes.sensibleDefaults = {
|
252 | 253 | }
|
253 | 254 | ```
|
254 | 255 |
|
| 256 | +Under the hood `VueTypes.sensibleDefaults` is a plain object with just some added _magic_. That let's you play with it like you'd do with every other object. |
| 257 | +
|
| 258 | +For example you can remove some of the default values by leveraging [object rest spread](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals) or [lodash.omit](https://lodash.com/docs/4.17.11#omit) like functions. |
| 259 | +
|
| 260 | +```js |
| 261 | +// copy every default value but boolean |
| 262 | + |
| 263 | +console.log(VueTypes.bool.default) |
| 264 | +// logs true |
| 265 | + |
| 266 | +const { bool, ...newDefaults } = VueTypes.sensibleDefaults |
| 267 | + |
| 268 | +VueTypes.sensibleDefaults = newDefaults |
| 269 | +// or VueTypes.sensibleDefaults = _.omit(VueTypes.sensibleDefaults, ['bool']) |
| 270 | + |
| 271 | +console.log(VueTypes.bool.default) |
| 272 | +// logs undefined |
| 273 | +``` |
| 274 | +
|
255 | 275 | ### Custom Types
|
256 | 276 |
|
257 | 277 | Custom types are a special kind of types useful to describe complex validation requirements. By design each custom type:
|
@@ -428,6 +448,99 @@ export default {
|
428 | 448 | }
|
429 | 449 | ```
|
430 | 450 |
|
| 451 | +### Extending VueTypes |
| 452 | +
|
| 453 | +You can extend VueTypes with your own types via `VueTypes.extend({...})`. The method accepts an object with every key supported by [Vue prop validation objects](https://vuejs.org/v2/guide/components-props.html#Prop-Validation) plus the following custom properties: |
| 454 | +
|
| 455 | +- `name`: (string, required) The type name. Will be exposed as VueType.<name> |
| 456 | +- `validate`: (boolean, default: `false`) If `true` the type will have a `validate` method like native types. |
| 457 | +- `getter`: (boolean, default: `false`) If `true` will setup the type as an accessor property (like, for example `VueTypes.string`) else will setup the type as a configurable method (like, for example `VueTypes.arrayOf`). |
| 458 | +
|
| 459 | +Examples: |
| 460 | +```js |
| 461 | +// as an accessor type |
| 462 | +VueTypes.extend({ |
| 463 | + name: 'negative', |
| 464 | + getter: true, |
| 465 | + type: Number, |
| 466 | + validator: (v) => v < 0 |
| 467 | +}) |
| 468 | + |
| 469 | +const negativeProp = VueTypes.negative |
| 470 | + |
| 471 | +// as a configurable method |
| 472 | +VueTypes.extend({ |
| 473 | + name: 'negativeFn', |
| 474 | + type: Number, |
| 475 | + validator: (v) => v < 0 |
| 476 | +}) |
| 477 | + |
| 478 | +const negativeProp2 = VueTypes.negativeFn() // <-- we need to call it |
| 479 | +``` |
| 480 | +
|
| 481 | +Note that if `getter` is set to `false`, arguments passed to the type will be passed to the `validator` method together with the prop value: |
| 482 | +
|
| 483 | +```js |
| 484 | +VueTypes.extend({ |
| 485 | + name: 'maxLength', |
| 486 | + // getter: false, this is the default |
| 487 | + type: String, |
| 488 | + validator: (max, v) => v.length <= max |
| 489 | +}) |
| 490 | + |
| 491 | +const maxLengthType = VueTypes.maxLength(2) |
| 492 | + |
| 493 | +maxLengthType.validator('ab') // true |
| 494 | +maxLengthType.validator('abcd') // false |
| 495 | +``` |
| 496 | +
|
| 497 | +#### Typescript |
| 498 | +
|
| 499 | +When used in a TypeScript project, types added via `.extend()` might fail type checking. In order to instruct TypeScript about your custom types you can use the following pattern: |
| 500 | +
|
| 501 | +```ts |
| 502 | +// propTypes.ts |
| 503 | + |
| 504 | +// import |
| 505 | +// - VueTypes library |
| 506 | +// - validation object interface (VueTypeDef) |
| 507 | +// - the default VueType interface (VueTypesInterface) |
| 508 | +import VueTypes, { VueTypeDef, VueTypesInterface } from 'vue-types' |
| 509 | + |
| 510 | +interface ProjectTypes extends VueTypesInterface { |
| 511 | + //VueTypeDef accepts the prop expected type as argument |
| 512 | + maxLength(max: number): VueTypeDef<string> |
| 513 | +} |
| 514 | + |
| 515 | +VueTypes.extend({ |
| 516 | + name: 'maxLength', |
| 517 | + type: String, |
| 518 | + validator: (max: number, v: string) => v.length <= max |
| 519 | +}) |
| 520 | + |
| 521 | +export default VueTypes as ProjectTypes |
| 522 | +``` |
| 523 | +
|
| 524 | +Then import the newly created `propTypes.ts` instead of `vue-types`: |
| 525 | +
|
| 526 | +```html |
| 527 | +<!-- MyComponent.vue --> |
| 528 | +<template> |
| 529 | +<!-- template here --> |
| 530 | +</template> |
| 531 | +<script lang="ts"> |
| 532 | +import Vue from "vue"; |
| 533 | +import VueTypes from "./prop-types"; |
| 534 | + |
| 535 | +export default Vue.extend({ |
| 536 | + name: "MyComponent", |
| 537 | + props: { |
| 538 | + msg: VueTypes.maxLength(2) |
| 539 | + } |
| 540 | +}); |
| 541 | +</script> |
| 542 | +``` |
| 543 | +
|
431 | 544 | ### Utilities
|
432 | 545 |
|
433 | 546 | `vue-types` exposes some utility functions on the `.utils` property:
|
|
0 commit comments