Components in Now.js provide a robust event handling system that allows you to
Now.getManager('component').define('button-counter', {
state: {
count: 0
},
methods: {
handleClick(e) {
this.state.count++;
}
},
template: `
<button onclick="methods.handleClick">
Clicked {{count}} times
</button>
`
});
Event handlers automatically have access to
this.state
- Component statethis.methods
- Component methodsthis.element
- Component root elementNow.getManager('component').define('scroll-watcher', {
mounted() {
// Add scroll listener when component mounts
window.addEventListener('scroll', this.methods.handleScroll);
},
beforeDestroy() {
// Remove scroll listener when component is destroyed
window.removeEventListener('scroll', this.methods.handleScroll);
},
methods: {
handleScroll(e) {
// Handle scroll event
}
}
});
Now.js automatically handles event cleanup when components are destroyed, preventing memory leaks.
Now.getManager('component').define('custom-form', {
methods: {
submitForm(data) {
// Emit custom event
this.emit('form:submit', {
data,
timestamp: Date.now()
});
}
}
});
Now.getManager('component').define('form-handler', {
mounted() {
// Listen for custom event
this.on('form:submit', this.methods.handleSubmit);
},
methods: {
handleSubmit(e) {
const { data, timestamp } = e.detail;
// Handle form submission
}
}
});
Now.js supports efficient event delegation for handling multiple similar elements
Now.getManager('component').define('todo-list', {
template: `
<ul onclick="methods.handleClick" class="todo-list">
{{#each items}}
<li data-id="{{id}}">{{text}}</li>
{{/each}}
</ul>
`,
methods: {
handleClick(e) {
const item = e.target.closest('li');
if (item) {
const id = item.dataset.id;
// Handle item click
}
}
}
});
Now.getManager('component').define('search-input', {
mounted() {
this.debouncedSearch = this.debounce(
this.methods.performSearch,
300
);
},
methods: {
handleInput(e) {
this.debouncedSearch(e.target.value);
},
performSearch(query) {
// Actual search implementation
}
}
});
Now.getManager('component').define('infinite-scroll', {
mounted() {
this.throttledScroll = this.throttle(
this.methods.checkScroll,
100
);
window.addEventListener('scroll', this.throttledScroll);
},
methods: {
checkScroll() {
// Load more content logic
}
}
});
methods: {
handleClick(e) {
e.stopPropagation();
// Handle click without bubbling
}
}
methods: {
handleSubmit(e) {
e.preventDefault();
// Custom form handling
}
}
beforeDestroy
hookon(event, handler)
off(event, handler)
emit(event, data)
debounce(fn, wait)
throttle(fn, limit)
event.detail
event.target
event.currentTarget
Now.getManager('component').define('login-form', {
template: `
<form onsubmit="methods.handleSubmit">
<input type="text" name="username" onchange="methods.handleInput">
<input type="password" name="password" onchange="methods.handleInput">
<button type="submit">Login</button>
</form>
`,
state: {
formData: {}
},
methods: {
handleInput(e) {
this.state.formData[e.target.name] = e.target.value;
},
handleSubmit(e) {
e.preventDefault();
this.emit('login:attempt', this.state.formData);
}
}
});
// Parent component
Now.getManager('component').define('message-app', {
mounted() {
this.on('message:send', this.methods.handleMessageSend);
},
methods: {
handleMessageSend(e) {
const message = e.detail;
// Handle message sending
}
}
});
// Child component
Now.getManager('component').define('message-input', {
methods: {
sendMessage(text) {
this.emit('message:send', {
text,
timestamp: Date.now()
});
}
}
});