Skip to content

Add registerHooks method to Component decorator #46

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Dec 17, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,59 @@ class MyComp extends Vue {
}
```

### Adding Custom Hooks

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:

```js
// class-component-hooks.js
import Component from 'vue-class-component'

// Register the router hooks with thier names
Component.registerHooks([
'beforeRouteEnter',
'beforeRouteLeave'
])
```

```js
// MyComp.js
import Vue from 'vue'
import Component from 'vue-class-component'

@Component
class MyComp extends Vue {
// The class component now treats beforeRouteEnter
// and beforeRouteLeave as Vue Router hooks
beforeRouteEnter () {
console.log('beforeRouteEnter')
}

beforeRouteLeave () {
console.log('beforeRouteLeave')
}
}
```

Note that you have to register the hooks before component definition.

```js
// main.js

// Make sure to register before importing any components
import './class-component-hooks'

import Vue from 'vue'
import MyComp from './MyComp'

new Vue({
el: '#app',
components: {
MyComp
}
})
```

### Build the Example

``` bash
Expand Down
4 changes: 2 additions & 2 deletions src/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as Vue from 'vue'
import { VueClass } from './declarations'
import { collectDataFromConstructor } from './data'

const internalHooks = [
export const $internalHooks = [
'data',
'beforeCreate',
'created',
Expand Down Expand Up @@ -34,7 +34,7 @@ export function componentFactory (
return
}
// hooks
if (internalHooks.indexOf(key) > -1) {
if ($internalHooks.indexOf(key) > -1) {
options[key] = proto[key]
return
}
Expand Down
19 changes: 14 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
import * as Vue from 'vue'
import { VueClass } from './declarations'

import { componentFactory } from './component'
import { componentFactory, $internalHooks } from './component'

export { createDecorator } from './util'

export default function Component <U extends Vue>(options: Vue.ComponentOptions<U>): <V extends VueClass>(target: V) => V
export default function Component <V extends VueClass>(target: V): V
export default function Component <V extends VueClass>(options: Vue.ComponentOptions<any> | V): any {
function Component <U extends Vue>(options: Vue.ComponentOptions<U>): <V extends VueClass>(target: V) => V
function Component <V extends VueClass>(target: V): V
function Component <V extends VueClass, U extends Vue>(
options: Vue.ComponentOptions<U> | V
): any {
if (typeof options === 'function') {
return componentFactory(options)
}
return function (Component: V) {
return componentFactory(Component, options)
}
}

namespace Component {
export function registerHooks (keys: string[]): void {
$internalHooks.push(...keys)
}
}

export default Component
15 changes: 15 additions & 0 deletions test/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,21 @@ describe('vue-class-component', () => {
expect(destroyed).to.be.true
})

it('hooks: adding custom hooks', () => {
Component.registerHooks(['beforeRouteEnter'])

@Component
class MyComp extends Vue {
static options: any

beforeRouteEnter () {
return 'beforeRouteEnter'
}
}

expect(MyComp.options.beforeRouteEnter()).to.equal('beforeRouteEnter')
})

it('data: should collect from class properties', () => {
@Component({
props: ['foo']
Expand Down