Reputation: 1266
I have a custom component in Vue.js(2) as:
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 component
<modal-panel title="New User" id="userModal" @confirm="doSomething">...</modal-panel>
As seen from the component code, confirm has been inserted into the props and on the button code in the template there is a conditional rendering according to whether confirm listener attached or not. However, button is not rendered. I checked component dom and properties, but there is not such an info.
Is it possible to make conditional rendering according to whether a specific listener attached to component in vue.js?
Thanks.
Upvotes: 4
Views: 8116
Reputation: 82459
Since Vue 2.4, Vue components have a $listeners
property.
Contains parent-scope v-on event listeners (without .native modifiers).
This is documented here. You can determine whether or not the parent is listening to a particular event by examining the $listeners
property.
It's not generally good practice for a component to reach out of itself to determine things.
I would recommend instead that you have a confirm
callback property. You can pass a function in as a property. Then you can decide to show/hide the button on whether you received the callback or not.
Vue.component("modal",{
props:["confirm"],
template: `
<div>
<h1>Modal</h1>
<button v-if="confirm" @click="confirm">Confirm</button>
</div>
`
})
Edit
You can determine if there is a handler defined on a component for a given event, but it requires examining an internal Vue property, and you should only use this 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
property of the component will contain the handler, if a handler is defined from the parent.
Upvotes: 5
Reputation: 193261
You need to bind your function with v-bind
or :
instead of just passing it as a string. So use :confirm
syntax:
<modal-panel title="New User" id="userModal" :confirm="doSomething"></modal-panel>
Then in component template simply 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>
Upvotes: 0