File tree 6 files changed +101
-3
lines changed
6 files changed +101
-3
lines changed Original file line number Diff line number Diff line change @@ -64,6 +64,40 @@ class App {
64
64
65
65
You may also want to check out the ` @prop ` and ` @watch ` decorators provided by [ vue-property-decorators] ( https://github.com/kaorun343/vue-property-decorator ) .
66
66
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
+
67
101
### Build the Example
68
102
69
103
``` bash
Original file line number Diff line number Diff line change @@ -17,6 +17,11 @@ const internalHooks = [
17
17
'render'
18
18
]
19
19
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
+
20
25
export function componentFactory (
21
26
Component : VueClass ,
22
27
options : Vue . ComponentOptions < any > = { }
@@ -53,6 +58,11 @@ export function componentFactory (
53
58
}
54
59
} )
55
60
61
+ // decorate options
62
+ $decoratorQueue . forEach ( fn => fn ( options ) )
63
+ // reset for other component decoration
64
+ $decoratorQueue = [ ]
65
+
56
66
// find super
57
67
const superProto = Object . getPrototypeOf ( Component . prototype )
58
68
const Super : VueClass = superProto instanceof Vue
Original file line number Diff line number Diff line change 1
1
import * as Vue from 'vue'
2
2
import { VueClass } from './declarations'
3
-
4
- const noop = ( ) => { }
3
+ import { noop } from './util'
5
4
6
5
export function collectDataFromConstructor ( vm : Vue , Component : VueClass ) {
7
6
// Create dummy Vue instance to collect
Original file line number Diff line number Diff line change @@ -3,6 +3,8 @@ import { VueClass } from './declarations'
3
3
4
4
import { componentFactory } from './component'
5
5
6
+ export { createDecorator } from './util'
7
+
6
8
export default function Component < U extends Vue > ( options : Vue . ComponentOptions < U > ) : < V extends VueClass > ( target : V ) => V
7
9
export default function Component < V extends VueClass > ( target : V ) : V
8
10
export 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'
2
2
import { expect } from 'chai'
3
3
import * as Vue from 'vue'
4
4
@@ -143,4 +143,36 @@ describe('vue-class-component', () => {
143
143
expect ( a . a ) . to . equal ( 1 )
144
144
expect ( a . b ) . to . equal ( 2 )
145
145
} )
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
+ } )
146
178
} )
You can’t perform that action at this time.
0 commit comments