Directives

Class

Makes your class visible to VueTypescript as a directive. The behavior of the decorator is very similar to @Component.

Options

Option Description
Name of the directive.
Note: Vue will prefix your name by v-, so if you name your directive demo, you will have to write v-demo in your template.
Group(s) on which the directive should be registered in the VueBuilder.
Custom factory function that will be called each time a new instance of the directive is created. A use-case is discussed in the Dependency injection section.

Example

A directive is just a normal class where you define lifecycle methods that will be called by Vue:

@Directive('demo')
export default class Demo {
    public mounted(el: Element, bindings: DirectiveBinding, vNode: VNode, prevNode: VNode|null) {
        el.style.border = '1px solid red';
    }
}
<div v-demo>My borders are red!</div>

WARNING

Please note that even if we named our directive demo, we still need to add v- in front. That's because Vue prefixes it automatically.

Instances management

Where @Directive becomes useful is on how it handles instances.

Each time you use your directive, a new instance is created (and destroyed when the directive is destroyed).

What makes it powerful is that the instance is kept between lifecycle calls. Meaning you can store values specific to your particular instance of the directive in the class, because each usage of the directive in the page will have it's own instance. Just like a component.

For example, let's count how many view updates occurred on a component:

import { Directive } from "@banquette/vue-typescript";

@Directive({
    name: 'update-counter',
    group: 'debug'
})
export default class UpdateCounter {
    public count: number = 0;

    public mounted() {
        console.log('update-counter mounted');
    }

    public updated(el: HTMLElement): void {
        ++this.count;
        console.log(`"${el.innerText}" has been updated ${this.count} times.`);
    }

    public unmounted() {
        console.log('update-counter unmounted');
    }
}

You can then use it anytime you want, each usage will have its own counter:

<my-component v-update-counter>Edit</my-component>
<my-component v-update-counter>Send</my-component>

WARNING

A directive cannot extend from the base class Vue because it only applies to components.