Introduction
Let's face it, building a fully responsive website can be a daunting task and while the functionality CSS provides are usually enough to make your site adapt to the various screen sizes, there are times when you need a little JavaScript to get it just right and nail that smooth user experience on every device.
Imagine for a second, you're building a dashboard for some e-commerce store to manage all sorts of data and you have a sidebar for navigating the various menus. Naturally the sidebar is the less important component of the page so when you want to adjust for smaller screen sizes, this is the component that gives way. We can hide the sidebar completely on mobile and even show a different variant of the sidebar on tablets.
JavaScript media queries offer the flexibility to conditionally render components which brings performance benefits because you don't have to render elements that are not visible to the user.
The Composable
Composables in Vue 3 are like hooks in react. They provide an intuitive way to extract reactive state and functionality to separate modules or as you will, composables.
Note: The code here leverages features unique to Vue 3 as it makes use of the composition API.
We're going to build a media query composable that accepts a media query string and essentially listens for changes in the window size and returns a variable that tells us if the current window size matches the query string.
// useMedia.js
import { ref, watchEffect } from "vue";
export const useMedia = (query) => {
const matches = ref(true);
watchEffect((onInvalidate) => {
const media = window.matchMedia(query);
if(media.matches !== matches) {
matches.value = media.matches;
}
const onChange = () => {
matches.value = media.matches;
}
media.addEventListener("change", onChange);
onInvalidate(() => {
media.removeEventListener("change", onChange);
});
});
return matches
}
Usage
import { useMedia } from "../../composables/useMedia";
...
const isMobile = useMedia("(max-width: 425px)")
...
In the snippet above we use the watchEffect
function to subscribe to changes in the matches
variable. In the watchEffect callback, we are listening for a change event on the matchMedia
property of the window object. When a change is detected, it calls the onChange
function which will update the matches
reactive object.
We also have an onInvalidate
function being called, which receives a callback function where we remove the event listener. This is essentially a clean-up function like you'd have in a react useEffect
hook. This lets us cancel all subscriptions when the component is unmounted.
This is how we can easily build our own custom re-usable function to use JavaScript media queries in our components. If you have any questions or thoughts on this, drop a comment below.
References
JavaScript Media Queries
Composables
Side Effect Invalidation
Top comments (1)
Thanks but there is a small mistake
it shoule be