File tree Expand file tree Collapse file tree 6 files changed +101
-3
lines changed Expand file tree Collapse file tree 6 files changed +101
-3
lines changed Original file line number Diff line number Diff line change @@ -64,6 +64,40 @@ class App {
6464
6565You may also want to check out the ` @prop ` and ` @watch ` decorators provided by [ vue-property-decorators] ( https://github.com/kaorun343/vue-property-decorator ) .
6666
67+ ### Create Custom Decorators
68+
69+ You can extend the functionality of this library by creating your own decorators. vue-class-component provides ` createDecorator ` helper to create custom decorators. ` createDecorator ` expects a callback function as the 1st argument and the callback will receive following arguments:
70+
71+ - ` options ` : Vue component options object. Changes for this object will affect the provided component.
72+ - ` key ` : The property or method key that the decorator is applied.
73+ - ` parameterIndex ` : The index of a decorated argument if the custom decorator is used for an argument.
74+
75+ Example of creating ` NoCache ` decorator:
76+
77+ ``` js
78+ // decorators.js
79+ import { createDecorator } from ' vue-class-component'
80+
81+ export const NoCache = createDecorator ((options , key ) => {
82+ // component options should be passed to the callback
83+ // and update for the options object affect the component
84+ options .computed [key].cache = false
85+ })
86+ ```
87+
88+ ``` js
89+ import { NoCache } from ' ./decorators'
90+
91+ @Component
92+ class MyComp extends Vue {
93+ // the computed property will not be cached
94+ @NoCache
95+ get random () {
96+ return Math .random ()
97+ }
98+ }
99+ ```
100+
67101### Build the Example
68102
69103``` bash
Original file line number Diff line number Diff line change @@ -17,6 +17,11 @@ const internalHooks = [
1717 'render'
1818]
1919
20+ // Property, method and parameter decorators created by `createDecorator` helper
21+ // will enqueue functions that update component options for lazy processing.
22+ // They will be executed just before creating component constructor.
23+ export let $decoratorQueue : ( ( options : Vue . ComponentOptions < Vue > ) => void ) [ ] = [ ]
24+
2025export function componentFactory (
2126 Component : VueClass ,
2227 options : Vue . ComponentOptions < any > = { }
@@ -53,6 +58,11 @@ export function componentFactory (
5358 }
5459 } )
5560
61+ // decorate options
62+ $decoratorQueue . forEach ( fn => fn ( options ) )
63+ // reset for other component decoration
64+ $decoratorQueue = [ ]
65+
5666 // find super
5767 const superProto = Object . getPrototypeOf ( Component . prototype )
5868 const Super : VueClass = superProto instanceof Vue
Original file line number Diff line number Diff line change 11import * as Vue from 'vue'
22import { VueClass } from './declarations'
3-
4- const noop = ( ) => { }
3+ import { noop } from './util'
54
65export function collectDataFromConstructor ( vm : Vue , Component : VueClass ) {
76 // Create dummy Vue instance to collect
Original file line number Diff line number Diff line change @@ -3,6 +3,8 @@ import { VueClass } from './declarations'
33
44import { componentFactory } from './component'
55
6+ export { createDecorator } from './util'
7+
68export default function Component < U extends Vue > ( options : Vue . ComponentOptions < U > ) : < V extends VueClass > ( target : V ) => V
79export default function Component < V extends VueClass > ( target : V ) : V
810export default function Component < V extends VueClass > ( options : Vue . ComponentOptions < any > | V ) : any {
Original file line number Diff line number Diff line change 1+ import * as Vue from 'vue'
2+ import { $decoratorQueue } from './component'
3+
4+ export const noop = ( ) => { }
5+
6+ export function createDecorator (
7+ factory : ( options : Vue . ComponentOptions < Vue > , key : string ) => void
8+ ) : ( target : Vue , key : string ) => void
9+ export function createDecorator (
10+ factory : ( options : Vue . ComponentOptions < Vue > , key : string , index : number ) => void
11+ ) : ( target : Vue , key : string , index : number ) => void
12+ export function createDecorator (
13+ factory : ( options : Vue . ComponentOptions < Vue > , key : string , index : number ) => void
14+ ) : ( target : Vue , key : string , index : any ) => void {
15+ return ( _ , key , index ) => {
16+ if ( typeof index !== 'number' ) {
17+ index = undefined
18+ }
19+ $decoratorQueue . push ( options => factory ( options , key , index ) )
20+ }
21+ }
Original file line number Diff line number Diff line change 1- import Component from '../lib/index'
1+ import Component , { createDecorator } from '../lib/index'
22import { expect } from 'chai'
33import * as Vue from 'vue'
44
@@ -143,4 +143,36 @@ describe('vue-class-component', () => {
143143 expect ( a . a ) . to . equal ( 1 )
144144 expect ( a . b ) . to . equal ( 2 )
145145 } )
146+
147+ it ( 'createDecorator' , function ( ) {
148+ const Prop = createDecorator ( ( options , key ) => {
149+ // component options should be passed to the callback
150+ // and update for the options affect the component
151+ ( options . props || ( options . props = { } ) ) [ key ] = true
152+ } )
153+
154+ const NoCache = createDecorator ( ( options , key ) => {
155+ // options should have computed and methods etc.
156+ // that specified by class property accessors and methods
157+ const computedOption : Vue . ComputedOptions < Vue > = options . computed ! [ key ]
158+ computedOption . cache = false
159+ } )
160+
161+ @Component
162+ class MyComp extends Vue {
163+ @Prop foo : string
164+ @NoCache get bar ( ) : string {
165+ return 'world'
166+ }
167+ }
168+
169+ const c = new MyComp ( {
170+ propsData : {
171+ foo : 'hello'
172+ }
173+ } )
174+ expect ( c . foo ) . to . equal ( 'hello' )
175+ expect ( c . bar ) . to . equal ( 'world' )
176+ expect ( ( MyComp as any ) . options . computed . bar . cache ) . to . be . false
177+ } )
146178} )
You can’t perform that action at this time.
0 commit comments