Is it possible to access event listeners from a component in Vue.js 2

I have a custom component in Vue.js (2) like:

Vue.component("modal-panel", {
    props: {
        id: {
            required: true
        },
        title: {} ,
        size: {
            validator: function(value) {
                return !value || value=="lg" || value=="sm";
            }
        }, 
        confirmLabel: {
            "default": "Yes",
        }, 
        closeLabel: {
            "default": "No"
        },
        confirm: {
            type: Function
        }
    },
    //...
    template: `
        //...
        <button type="button" class="btn btn-primary confirm" data-dismiss="modal" v-on:click="$emit('confirm')" v-if="confirm">{{confirmLabel}}</button>
        //...
    `
}

      

And this is the code using the component

<modal-panel title="New User" id="userModal" @confirm="doSomething">...</modal-panel>

      

As you can see from the component code, the confirmation is inserted into props, and the button code in the template is conditional rendering depending on whether the confirmation receiver is attached or not. However, the button is not displayed. I checked the dom component and properties but there is no such information.

Is it possible to do conditional rendering depending on whether a particular listener is attached to a component in vue.js?

Thank.

+3


source to share


2 answers


It is not good practice for a component to reach out of itself, to define things.

I would recommend having a callback property instead confirm

. You can pass a function as a property. Then you can choose to show / hide the button whether a response was received or not.

Vue.component("modal",{
  props:["confirm"],
  template: `
    <div>
      <h1>Modal</h1>
      <button v-if="confirm" @click="confirm">Confirm</button>
    </div>
  `
})

      

An example .

Edit



You can determine if there is a component-specific handler for a given event, but it requires examining an internal Vue property and you should only use it at your own risk.

Vue.component("modal",{
  template: `
    <div>
      <h1>Modal</h1>
      <button v-if="hasConfirmHandler" @click="$emit('confirm')">Confirm</button>
    </div>
  `,
  computed:{
    hasConfirmHandler(){
      return !!this._events["confirm"]
    }
  }
})

      

The _events

component property will contain the handler if the handler is defined from the parent.

An example .

+2


source


You need to bind your function with v-bind

or :

instead of just passing it as a string. So use the syntax :confirm

:

<modal-panel title="New User" id="userModal" :confirm="doSomething"></modal-panel>

      



Then, in the component template, just use v-on:click="confirm()"

:

<button type="button" class="btn btn-primary confirm" data-dismiss="modal" 
  v-on:click="confirm()" 
  v-if="confirm">
  {{confirmLabel}}
</button>

      

0


source







All Articles