Image

build-a-gmail-clone-with-vue-3

3 min read
Last update: December 19, 2021

useKeydown Composable

For the starting code for this lesson, switch to branch: https://github.com/Code-Pop/build-gmail-clone-with-vue-3/tree/video-8-start

In this lesson, we’re going to abstract our onKeydown functionality to a function that can be reused in multiple components - and in doing so, we’re going to see a great use case of the Composition API.

We’re going to take this:

setup(props, {emit}) {
let onKeydown = (event) => {
if(event.key == 'Escape') {
emit('closeModal')
}
}

window.addEventListener('keydown', onKeydown)

onBeforeUnmount(() => {
window.removeEventListener('keydown', onKeydown)
})
}

And replace it with this:

setup({closeModal}) {
useKeydown({key: 'Escape', fn: () => { emit('closeModal')}})
}

So let’s start by copy-pasting it into another file with minimal modifications. We’ll call this file /compositions/useKeydown.js.

import { onBeforeUnmount } from 'vue';

export const useKeydown = function(fn) {
let onkey = function(event) {
if(event.key == 'Escape') {
fn()
}
}

window.addEventListener('keydown', onkey);

onBeforeUnmount(()=> {
window.removeEventListener('keydown', onkey);
})
}

export default useKeydown;

This file exports the useKeydown function, which takes one argument (fn) and calls that function when the Escape key is hit. We can call it like this:

import { useKeydown } from '../composition/useKeydown'

export default {
setup(props, {emit}){
useKeydown(() => {emit('closeModal')})
}
}

Of course, this is a very limited abstraction, but it’s useful to show how we can move the function to its own file. Let’s make it a little bit more useful by letting the caller configure which key will trigger the function.

export const useKeydown = function(keyCombo) {
let onKey = function(event) {
if(event.key == keyCombo.key) {
keyCombo.fn()
}
}
//... rest of file is the same
}
setup(props, {emit) {
useKeydown({key: 'Escape', fn: () => {emit('closeModal')})
}

This is great! It’s the functionality that we described at the start.

But we can go a bit further and tackle another use case - what if the user wants to configure multiple keys with one call to useKeydown? This is a reasonable use case, and in fact will be used very soon in this course, so let’s tackle it now.

The answer is to match a keyCombo’s key with the pressed key, and then run the given function.

export const useKeydown = function(keyCombos) {
let onkey = function(event) {
let kc = keyCombos.find(kc => kc.key == event.key )
if(kc) {
kc.fn()
}
}
//... rest of file is the same
}
setup(props, {emit}) {
useKeydown([
{key: 'Escape', fn: () => {emit('closeModal')}},
{key: 'Enter', fn: () => { console.log('logging for demonstration purposes') }
])
}

For the ending code for this lesson, switch to branch: https://github.com/Code-Pop/build-gmail-clone-with-vue-3/tree/video-8-end

Jeffrey teaches an 8-week beginning Vue course with guaranteed results. Built on top of the VueMastery curriculum, with extra hands-on assignments and personal attention. You can find it here.