Use your component
Now that your component is configured and ready to use, you have two possibilities to use it:
- Import your component manually in an existing
Vue
app, - Use the VueBuilder provided by
Banquette
.
VueBuilder
The VueBuilder
is a utility class that stores every Vue
component and directive created using the @Component
or @Directive
decorator (assuming the group
option is not set to null
).
NOTE
Both @Component
and @Directive
have a group
option that controls in which group(s) they will be registered in the builder. You can set it to null
so they are not registered at all.
Doing this allows you to do this:
import { VueBuilder } from '@banquette/vue-typescript';
// Here we import what we need.
import '@banquette/vue-ui/button';
import '@banquette/vue-ui/dialog';
// Then we create an app.
// The component that have been imported are automatically added to the app.
VueBuilder.CreateAppAndMount('#app');
Groups
You can separate your components and directives in different group to better organize your dependencies:
import { Component, VueBuilder } from "@banquette/vue-typescript";
@Component({
name: 'form-text',
group: 'form'
})
class FormText {
[...]
}
// Internally, @Component will call the VueBuilder like this:
VueBuilder.RegisterComponent('form-text', FormText, 'form');
WARNING
You must define a name for your component for it to be registered in the VueBuilder
. Otherwise it will be ignored.
Usage
Here are some usage examples of the builder:
// Create an app that will include all components and directives registered in the "default" group.
VueBuilder.CreateApp();
// Same for the "form" group.
VueBuilder.CreateApp('form');
// Or with multiple groups.
VueBuilder.CreateApp(['form', 'modals']);
// Or to use all known components and directives.
VueBuilder.CreateApp('*');
// With options (the second argument is the object you would normally pass to "createApp()").
VueBuilder.CreateApp('form', {
compilerOptions: {
comment: true
}
});
// Same as `VueBuilder.CreateApp(...).mount('#app')`.
VueBuilder.CreateAppAndMount('#app', 'form', {
compilerOptions: {
delimiters: ['${', '}']
}
});
You can also create the app yourself and apply the configuration of the builder afterwards:
import { createApp } from 'vue';
import { VueBuilder } from "@banquette/vue-typescript";
// Create an app.
const app = createApp({...});
// Will merge the global options and register the corresponding components and directives.
VueBuilder.ApplyToExistingApp(app);
Global options
VueBuilder
also offers a SetVueOption
method allowing you to set an option globally that will then be merged with all apps created with it:
// Will change the delimiters of all apps created using the builder.
VueBuilder.SetVueOptions({compilerOptions: {
delimiters: ['${', '}']
});
// You can call it multiple times, options will be merged
VueBuilder.SetVueOptions({compilerOptions: {
comment: true
});
// Will result:
// {
// compilerOptions: {
// delimiters: ['${', '}'],
// comment: true
// }
// }
TIP
Options passed to the CreateApp
or CreateAppAndMount
have the priority to these defined globally.
Manual use
You can use the component constructor directly in your Vue
instance:
import { createApp } from 'vue';
import { ButtonComponent } from '@banquette/vue-ui/button';
// Here the component name will be "button-component".
createApp({
components: {ButtonComponent}
}).mount('#app');
// If you want to rename it.
createApp({
components: {'my-button': ButtonComponent}
}).mount('#app')
TIP
If you register your components or directives this way, the name
option of their decorator is not used, so you must name them yourself or do with the default name Vue
will give them.
WARNING
BUT BEWARE with directives! You can't register them directly from their constructor like you do with components.
To illustrate, please take the following example:
import { createApp } from 'vue';
import { Button } from './components/button'; // A custom component
import { DemoDirective } from './directives/demo'; // A custom directive
const app = createApp({
components: {Button}, // Will work
directives: {DemoDirective} // Will NOT work
});
This is because internally, when Vue
sees that a directive is a function, it wraps it into an object defining a mounted
and updated
callback.
This prevents the use of a constructor as a directive definition.
So if you need to create your app manually, you have to use VueBuilder
to get the definition of the directive:
import { createApp } from 'vue';
import { Component, VueBuilder } from "@banquette/vue-typescript";
import { Button } from './components/button'; // A custom component
import { DemoDirective } from './directives/demo'; // A custom directive
const app = createApp({
components: {Button}, // OK
directives: {'demo': VueBuilder.GetDirectiveDefinition(DemoDirective).directive} // OK
});
Accessing Vue variables
As you can see in all previous examples, components don't have to inherit from any base class to work. This is by design, to make the integration as easy as possible.
But this also prevents you to access Vue
specific properties like $attrs
, $slots
, etc.
If you need these, you have to inherit from the Vue
base class of @banquette/vue-typescript
:
import { Component, Vue } from '@banquette/vue-typescript';
@Component()
export class MyComponent extends Vue {
public mounted(): void {
// Because you inherit from "Vue", `vue-typescript` will automatically
// make public attributes from Vue available in the component.
console.log(this.$slots);
}
}
This class also comes with a few useful utilities:
import { Component, Vue } from '@banquette/vue-typescript';
@Component()
export class MyComponent extends Vue {
public mounted(): void {
// Test if a slot named "title" is defined.
this.hasSlot('title');
// Test if a slot named "title" exists and has content in it.
// WARNING: this renders the slot.
this.hasNonEmptySlot('title');
// Test if a slot exists, render it if so and extract is text content.
// Returns `null` is the slot doesn't exist.
this.getSlotTextContent('title');
// Try to get a reference on a specific parent component.
// This method will return the actual TypeScript instance of the component, if found.
this.getParent(AlertComponent);
// Can also get it by its name.
// WARNING: the name defined in the @Component() decorator is used here.
// If you renamed the component on use, you must still reference it with the "`VueTypescript` name".
this.getParent('bt-form');
// Test if component is found in the parent hierarchy.
// Same as above for the name.
this.hasParent('bt-button');
// Gets the whole `VueTypescript` metadata object associated with the current component.
this.getMetadata();
}
}