Handling Events
This guide explains how to add event listeners to a component.
Adding event listeners
Once nodes have been declared in nodes
, an entry for them can be added to the events option. The entry must have the exact same name as the node and must be a function that returns an event object. Each key in the event object must be a valid event type and the corresponding value must a function that handles that event.
defineComponent({
nodes: {
button: {
type: 'element',
tagName: 'button',
},
},
events: {
button() {
return {
click: () => {
// the button was clicked, do something ...
},
};
},
},
});
Reserved event types
$window
, $document
, and $root
are reserved properties on the events
option that should be used add events to the Window, Document, and root element respectively.
defineComponent({
events: {
$window() {
return {
resize: () => {
// the window resized, do something ...
},
};
},
$document() {
return {
click: () => {
// the document was clicked, do something ...
},
};
},
$root() {
return {
click: () => {
// the root element was clicked, do something ...
},
};
},
},
});
Handling multiple elements
For nodes that are an array (via the query-all
or custom
type), the events will be assigned directly to each element. Also, the index of the array will be passed as the first argument and can be used to differentiate each element.
defineComponent({
nodes: {
multipleElements: {
type: 'query-all',
selector: '<some-selector>',
},
},
events: {
multipleElements(index) {
return {
click: () => {
console.log(`Element ${index} was clicked!`;
},
};
},
},
});
Moving handlers to methods
When desired, event handlers can be moved to the methods option and referenced via the this
keyword. This can be useful when handlers contain a lot of logic and become unwieldy.
- JavaScript
- TypeScript
defineComponent({
methods: {
handleClick() {},
},
events: {
$root() {
return {
click: this.handleClick,
};
},
},
});
defineComponent<{
$root: Element;
$state: {};
handleClick(): void;
}>({
methods: {
handleClick() {},
},
events: {
$root() {
return {
click: this.handleClick,
};
},
},
});
Adding custom events
The lifecycle hooks can be used add custom events and unconventional listeners like mutation observers and media query listeners to the component.
- JavaScript
- TypeScript
defineComponent({
methods: {
handleCustomEvent() {}
handleMutationObserver() {}
handleMediaQueryChange() {}
},
hooks: {
$setup() {
this.$root.addEventListener('click', this.handleCustomEvent);
this.mutationObserver = new MutationObserver(this.handleMutationObserver);
this.mutationObserver.observe(this.$root, { attributes: true });
this.mediaQueryList = window.matchMedia('(max-width: 600px)');
this.mediaQueryList.addEventListener('change', this.handleMediaQueryChange);
},
$teardown() {
this.$root.removeEventListener('click', this.handleCustomEvent);
this.mutationObserver.disconnect();
this.mediaQueryList.removeEventListener('change', this.handleMediaQueryChange);
},
},
});
defineComponent<{
$root: Element;
$state: {};
mutationObserver: MutationObserver,
mediaQueryList: MediaQueryList,
handleCustomEvent(): void,
handleMutationObserver(): void,
handleMediaQueryChange(): void,
}>({
methods: {
handleCustomEvent() {}
handleMutationObserver() {}
handleMediaQueryChange() {}
},
hooks: {
$setup() {
this.$root.addEventListener('click', this.handleCustomEvent);
this.mutationObserver = new MutationObserver(this.handleMutationObserver);
this.mutationObserver.observe(this.$root, { attributes: true });
this.mediaQueryList = window.matchMedia('(max-width: 600px)');
this.mediaQueryList.addEventListener('change', this.handleMediaQueryChange);
},
$teardown() {
this.$root.removeEventListener('click', this.handleCustomEvent);
this.mutationObserver.disconnect();
this.mediaQueryList.removeEventListener('change', this.handleMediaQueryChange);
},
},
});