hotkeys-js
hotkeys-js copied to clipboard
Vuejs version of Hotkeys
Hello,
Thanks for a wonderful keyboard binding library, I was trying to integrate this library in my vue project I and can't.
Does any one tried to implement in their vuejs project? If someone tried, guide me how to integrate it, that would be amazing.
Thanks! Rutvij
Mind sharing more about what you're trying to achieve? It would help if you can give us more insight into how deep do you want the lib to integrate with your project.
I'm currently using this lib in my project, but I'm not doing anything too complicated and it's just sitting on top of what I have. If that's what you want, feel free to check out the file where I'm using it.
Cheers!
You can use the hotkeys
function directly to bind and unbind hotkeys. I made an example of using it with Vue on CodeSandbox, but essentially you can use the mounted and beforeDestroy methods to bind a hotkey whenever a component is mounted on the screen (this assumes there's only one instance of this component mounted at a time):
import hotkeys from "hotkeys-js";
export default {
name: "ComponentWithHotkey",
mounted() {
hotkeys("a", () => this.hotkeyPressed());
},
beforeDestroy() {
hotkeys.unbind("a");
},
methods: {
hotkeyPressed() {
this.$emit("increment");
}
}
};
The problem is that the imported hotkeys
is a singleton, so you have to manually unbind all the bindings you made on a given component (cf. @jennings example). If you don't, Hotkeys will hold onto a reference of your component; it won't be freed from memory, and you'll rebind the same keys when the component is mounted again. It will build up the memory, the CPU usage, and may introduce bugs.
Unfortunately, if re-binding the same keys on a new component doesn't introduce bugs, you'll have a memory leak that will be hard to track.
@jaywcjlove A way to fix this would be to let users instantiate and manage their own Hotkeys instance(s) themselves, if that's possible. Or, without rewriting much, you could warn users if they're re-binding the same keys via a console.warn (maybe activated only via a debug flag to avoid spam)
@scambier Even if you had a separate instance of the hotkeys
object, you'd still need a clean-up step that gets called when the component is being unmounted. I'm not sure if having a separate instance of hotkeys
would solve the resource leak.
// hypothetical API for creating a hotkeys instance
import { makeHotkeysInstance } from "hotkeys-js";
export default {
name: "ComponentWithHotkey",
mounted() {
this.hotkeys = makeHotkeysInstance();
this.hotkeys("a", () => this.hotkeyPressed());
},
beforeDestroy() {
// still requires cleanup or else the arrow function
// will remain bound to the window's keydown event
this.hotkeys.destroy();
},
...
};
You're right, I'm not sure what I had in mind. But your example shows a nice way to do it: you don't have to keep an up-to-date list of unbind()
calls, as a single call to this.hotkeys.destroy()
could do the job. That'd be cleaner and less error-prone IMO
Sorry for responding to an old thread, but I took a different route by binding hotkeys to the Vue instance prototype. And only clean up using the scope functions in my components. This way the cleanup is simple and hotkeys is called only once.
Before calling new Vue() attach hotkeys: Vue.prototype.$keys = hotkeys.noConflict(true)
And in my components:
export default {
data: {
hotKeyScope: 'some-usefull-name'
},
created() {
this.$keys('enter', this.hotKeyScope, () => { /*...*/ })
},
beforeDestroy() {
this.$keys.deleteScope(this.hotKeyScope);
}
}
I've not tested all use/edge-cases, but worked well enough in my apps. My guess is that if you have multiple competing scopes on the same page, you'll have to manage these yourself.
Hi there, I made a composition-api version of this and published as vue-use-hotkeys
on npm. Try it out if interested.