Hello,
I am still learning Vuejs 3
(and JS in general) so for some of the simple tasks that might be easy to solve with the right tools - I come up with my own solutions (that are more complex sometimes )
This time I think I have done something that is worth sharing with other people. Basically I think I have created some kind of pattern for when you need to notify a certain part of the app about an event.
Approach 1, using mitt
:
Composable function
import mitt from "mitt";
const emitter = mitt();
export default function useEmitter() {
return {
emitter
};
}
In component A
<script>
import useEmitter from "@/use/useEmitter.js";
export default {
setup() {
const useEmitter = useEmitter();
useEmitter.emitter.emit("clicked");
}
}
</script>
In component B
<script>
import useEmitter from "@/use/useEmitter.js";
export default {
setup() {
const useEmitter = useEmitter();
useEmitter.emitter.on("clicked", () => {
console.log("Clicked!");
});
// p.s. don't forget to unsubscribe in onBeforeUnmount
}
}
</script>
Approach 2, using ref
/watch
Composable function
import { ref } from "vue";
const clickedToggle = ref(false);
export default function useEmitter() {
const notifyClicked = () => {
clickedToggle.value = !clickedToggle.value;
};
return {
clickedToggle,
notifyClicked,
};
}
In component A
<script>
import useEmitter from "@/use/useEmitter.js";
export default {
setup() {
const useEmitter = useEmitter();
useEmitter.notifyClicked();
}
}
</script>
In component B
<script>
import { watch } from "vue";
import useEmitter from "@/use/useEmitter.js";
export default {
setup() {
const useEmitter = useEmitter();
watch(useEmitter.clickedToggle, () => {
console.log("Clicked!");
});
}
}
</script>
Pros and cons associated with both solutions
mitt
pros
- supports passing event arguments (
emit('name', arguments)
)
cons
- need to unsubscribe from events explicitly
- dependency on 3rd party tool and all related cons (bundle size, maintenance, updates, learning curve)
using in-built functions
pros
- no need to learn anything new
- no need to install new dependencies (and all associated perks)
- no need to unsubscribe from events
cons
-
does not support passing arguments to events(see edit)
Epilogue
I guess I have not discovered something new. People must have used this for ages. It would be nice to hear from VueJS veterans (or just in general from Javascript devs) if this solution could even be considered a good programming practice or not⦠Or should I just stick to using an event bus for simple cases like this (event with no arguments).
p.s. also I have not tested the code above. I have just typed it in notepad so there might be some typos making the code not to compile, but the general idea should be there.
Edit (19.01.2022)
I now understand that you could even support āevent argumentsā by reading the value of the reference object being watched! i.e. in composable function:
const notifyClicked = (newValue) => {
clickedToggle.value = newValue;
};
and then when you need to read the argument/s you do:
watch(useEmitter.clickedToggle, () => {
console.log("Clicked!");
console.log(useEmitter.clickedToggle.value); // do something here
});
With this - the con is gone