euvl/vue-js-modal

[feature] A way to listen for custom events from programmatic modals

xaddict opened this issue · 7 comments

Problem:

I have a dynamic modal where the user can link two entities.
Depending on what they do in the modal I would like to emit a custom event because in all cases I need to do something else in the parent component:

  • this.$emit('reload-list')
  • this.$emit('entities-unlinked')
  • this.$emit('oh-crap')

With a non-programmatic modal this is easy to do:

<CustomCom @reload-list="reloadStuff" />

the parent component has a method reloadStuff and the modal in CustomCom can then emit reload-list

however, with a programmatic modal:

this.$modal.show(CustomCom, props, params, events)

this event just gets shot into the ether and there's no real way to catch it.

So I would like a way to add this to events:

this.$modal.show(
  CustomCom,
  { ...props },
  { ...params },
  {
    'before-open': this.beforeOpen,
    'before-close': this.beforeClose
    'reload-list': this.reloadStuff
  }
)

Version:

1.3.35

I have checked stackoverflow for solutions and 100% sure that this issue is not not related to my code.

You can pass functions as props. Here is how I'd do it:

Define the function to catch event from child component in parent

export default {
  name: 'ParentComp'
  methods: {
    catchChildEvent(eventFromChildComp) {
      console.log(eventFromChildComp)
    }
  }
}

Insert function as a prop in dynamic modal

this.$modal.show(
  ChildComp,
  {
     catchChildEvent: this.catchChildEvent
  },
  {
    name: 'ChildComp'
  },
  {
    'before-open': this.beforeOpen,
    'before-close': this.beforeClose
  }
)

Execute function in child component

<template>
  <div id="childComp">
    <a href="#" @click.prevent="eventOnChild('Hi, I came from child component!')" v-text="'click me!'" />
  </div>
</template>
export default {
  name: 'ChildComp',
  props: {
    catchChildEvent: {
      type: Function,
      default: () => {}
    }
  },
  methods: {
    eventOnChild(message) {
      this.catchChildEvent(message)
    }
  }
}

It's a pretty clean workaround so I will try it.

But I would prefer just using plain emitters :)

I would also like to use emitters, do you think that would be possible ?

临时解决方案

let vm = this;
this.$modal.show(
 {
  extends: CustomCom,
  created(){
      this.$on('reload-list', vm.reloadStuff )
  }
},
  { ...props },
  { ...params },
  {
    'before-open': this.beforeOpen,
    'before-close': this.beforeClose
  }
)
stale commented

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@poulSoul global listeners will be deprecated in Vue 3.

Functions like described @marcoelissa don't have this problem. So I will use that for now.

stale commented

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.