Vue.js event bus technique is sometime useful.
// ModalEvent.js import Vue from "vue" export const ModalEvent = new Vue()
<script> import Vue from "vue" import VModal from "vue-js-modal" import { ModalEvent } from "./ModalEvent" Vue.use(VModal) export default { created(){ ModalEvent.$on("openModal", () => { this.$modal.show("hello-modal") }) } } </script>
<!-- event trigger component --> <script> import { ModalEvent } from "./ModalEvent" export default { methods:{ onClick(){ ModalEvent.$emit("openModal") } } } </script>
But it have tiny problem that Event.$on
and Event.$emit
's event signature is string, and it's can easily mistake.
Solution
I found it's can solve with use Event.methods
.
// ModalEvent.js import Vue from "vue" const OPEN_MODAL = "openModal" export const ModalEvent = new Vue({ methods: { emitOpenModal(event){ this.$emit(OPEN_MODAL, event) }, onOpenModal(cb){ this.$on(OPEN_MODAL, cb) } } })
<script> import Vue from "vue" import VModal from "vue-js-modal" import { ModalEvent } from "./ModalEvent" Vue.use(VModal) export default { created(){ ModalEvent.onOpenModal( () => { this.$modal.show("hello-modal") }) } } </script>
<script> import { ModalEvent } from "./ModalEvent" export default { methods:{ onClick(){ ModalEvent.emitOpenModal() } } } </script>
Top comments (4)
Hello, Terrierscript.
could you please guide me to test this modal vuejs component with JEST ?
import Vue from 'vue'
import { TeamMember } from '@/components/TeamMember.vue'
import { mount } from "@vue/test-utils"
describe('TeamMember.vue', ()=>{
it('renders a link', () => {
const wrapper = mount(TeamMember)
expect(wrapper.text(true)).toEqual(true)
})
})
Sorry for late ( I missed this comment.)
Hmm, this solution is un-test friendly ( I noticed this now )
If I need test this, I mocked
ModalEvent
.use with jestjs.io/docs/en/manual-mocks#moc... or sinonjs.org/
cool! I find Redux/Vuex really confusing, but this EventBus method looks like a simpler solution.
You can even use this technique while still making use of Vuex.
I like it the most when I want to avoid storing extra stuff in state, like having some vue instance commit a flag, that another vue instance is watching. That would be like a vue1 -> state -> vue2 pathway.
I can instead just use the EventBus as like a side passage, just emit from 1 vue component and listen to it in the other one so I'm instead going vue1 -> EventBus -> vue2.