Using services
What are services?
When developping components for a web page, we often need to implement trivial task in multiple places such a reacting to the resize of the window, reacting to the user scroll. Services were created to standardize and simplify how we implement such behaviours.
The following services are exported by the @studiometa/js-toolkit
package:
useDrag
to implement drag behaviour with inertiauseScroll
to implement behaviour on scroll (throttled)useResize
to implement behaviour on window resize (debounced)useRaf
to implement loop behaviour withrequestAnimationFrame
usePointer
to implement behaviour reacting to the user pointer (mouse or touch)useKey
to implement behaviour reacting on keyboard interactionuseLoad
to implement behaviour on page load
TIP
Find all natively available services and their API details in the Services section from the API Reference.
Usage
As class methods
Services can be used via predefined class methods (called services hooks) when extending the Base
class. They will be automatically enabled when the component is mounted if the method is defined or if a listener has been added to its corresponding event.
The following service hooks and events are available:
scrolled
for theuseScroll
serviceresized
for theuseResize
serviceticked
for theuseRaf
servicemoved
for theusePointer
servicekeyed
for theuseKey
service
The services hooks diagram below present in greater detail what action will trigger a service method.
Using a service via its reserved method name
import { Base } from '@studiometa/js-toolkit';
class Component extends Base {
static config = {
name: 'Component',
};
scrolled(props) {
if (props.changed.y) {
console.log('User is scrolling vertically.');
}
}
}
Using a service via its corresponding event
import { Base } from '@studiometa/js-toolkit';
class Component extends Base {
static config = {
name: 'Component',
};
mounted() {
this.$on('scrolled', (props) => {
if (props.changed.y) {
console.log('User is scrolling vertically.');
}
});
}
}
Best practice
Services should always be used via the method API. The event API has been designed for library author.
Standalone
Services can be used outside of a Base
class by importing the use<Service>
functions from the package. Each use<Service>
function will return an object containing the following:
- an
add(key, callback)
function to add a new callback to the service - an
has(key)
function to test if the given key matches an added callback - a
remove(key)
function to remove a callback by its key - a
props()
function returning the properties of the service
For example, to do something when the user scrolls, you can use the "scrolled" service and its useScroll()
function:
import { useScroll } from '@studiometa/js-toolkit';
const scroll = useScroll();
const key = 'some-uniq-key';
// Add a callback for the service
scroll.add(key, (props) => {
// The `props` parameter is the same object
// returned by the `service.props()` method
console.log(props.y === scroll.props().y);
if (props.changed.y) {
console.log('User is scrolling vertically.');
}
});
// Test if the callback already exists or not
console.log(scroll.has(key)); // true
// Remove the callback
scroll.remove(key);
The service properties can also be destructured for simplicity:
const { add, remove, props, has } = useScroll();
Enabling/disabling a service
By default, if a service is used either via a class method or via an event, it will be enabled when the instance is mounted and will not be disabled until the instance is destroyed. This can sometimes be counterproductive for many reasons: performances, one-time behaviours, etc.
Services in a Base
instance are managed by a ServicesManager
available with the $services
property. This manager can help you manage which service is running or not.
For example, to toggle the scroll service only when a button has been clicked:
import { Base } from '@studiometa/js-toolkit';
class Component extends Base {
static config = {
name: 'Component',
refs: ['btn'],
};
onBtnClick() {
this.$services.toggle('scrolled');
}
scrolled() {
console.log('The scrolled service is enabled!');
}
}
API Reference
Learn more on the service manager in the API Reference.