Skip to content

Commit 543a2da

Browse files
authored
Add registerHooks method to Component decorator (vuejs#46)
* add registerHooks * update README for custom hooks * fix syntax error in readme * fix grammatical error * use namespace to bypass type assertion
1 parent bd8f389 commit 543a2da

File tree

4 files changed

+84
-7
lines changed

4 files changed

+84
-7
lines changed

README.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,59 @@ class MyComp extends Vue {
103103
}
104104
```
105105

106+
### Adding Custom Hooks
107+
108+
If you use some Vue plugins like Vue Router, you may want class components to resolve hooks that they provides. For that case, `Component.registerHooks` allows you to register such hooks:
109+
110+
```js
111+
// class-component-hooks.js
112+
import Component from 'vue-class-component'
113+
114+
// Register the router hooks with thier names
115+
Component.registerHooks([
116+
'beforeRouteEnter',
117+
'beforeRouteLeave'
118+
])
119+
```
120+
121+
```js
122+
// MyComp.js
123+
import Vue from 'vue'
124+
import Component from 'vue-class-component'
125+
126+
@Component
127+
class MyComp extends Vue {
128+
// The class component now treats beforeRouteEnter
129+
// and beforeRouteLeave as Vue Router hooks
130+
beforeRouteEnter () {
131+
console.log('beforeRouteEnter')
132+
}
133+
134+
beforeRouteLeave () {
135+
console.log('beforeRouteLeave')
136+
}
137+
}
138+
```
139+
140+
Note that you have to register the hooks before component definition.
141+
142+
```js
143+
// main.js
144+
145+
// Make sure to register before importing any components
146+
import './class-component-hooks'
147+
148+
import Vue from 'vue'
149+
import MyComp from './MyComp'
150+
151+
new Vue({
152+
el: '#app',
153+
components: {
154+
MyComp
155+
}
156+
})
157+
```
158+
106159
### Build the Example
107160

108161
``` bash

src/component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as Vue from 'vue'
22
import { VueClass } from './declarations'
33
import { collectDataFromConstructor } from './data'
44

5-
const internalHooks = [
5+
export const $internalHooks = [
66
'data',
77
'beforeCreate',
88
'created',
@@ -34,7 +34,7 @@ export function componentFactory (
3434
return
3535
}
3636
// hooks
37-
if (internalHooks.indexOf(key) > -1) {
37+
if ($internalHooks.indexOf(key) > -1) {
3838
options[key] = proto[key]
3939
return
4040
}

src/index.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
import * as Vue from 'vue'
22
import { VueClass } from './declarations'
3-
4-
import { componentFactory } from './component'
3+
import { componentFactory, $internalHooks } from './component'
54

65
export { createDecorator } from './util'
76

8-
export default function Component <U extends Vue>(options: Vue.ComponentOptions<U>): <V extends VueClass>(target: V) => V
9-
export default function Component <V extends VueClass>(target: V): V
10-
export default function Component <V extends VueClass>(options: Vue.ComponentOptions<any> | V): any {
7+
function Component <U extends Vue>(options: Vue.ComponentOptions<U>): <V extends VueClass>(target: V) => V
8+
function Component <V extends VueClass>(target: V): V
9+
function Component <V extends VueClass, U extends Vue>(
10+
options: Vue.ComponentOptions<U> | V
11+
): any {
1112
if (typeof options === 'function') {
1213
return componentFactory(options)
1314
}
1415
return function (Component: V) {
1516
return componentFactory(Component, options)
1617
}
1718
}
19+
20+
namespace Component {
21+
export function registerHooks (keys: string[]): void {
22+
$internalHooks.push(...keys)
23+
}
24+
}
25+
26+
export default Component

test/test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,21 @@ describe('vue-class-component', () => {
2525
expect(destroyed).to.be.true
2626
})
2727

28+
it('hooks: adding custom hooks', () => {
29+
Component.registerHooks(['beforeRouteEnter'])
30+
31+
@Component
32+
class MyComp extends Vue {
33+
static options: any
34+
35+
beforeRouteEnter () {
36+
return 'beforeRouteEnter'
37+
}
38+
}
39+
40+
expect(MyComp.options.beforeRouteEnter()).to.equal('beforeRouteEnter')
41+
})
42+
2843
it('data: should collect from class properties', () => {
2944
@Component({
3045
props: ['foo']

0 commit comments

Comments
 (0)