I am going to pass function as property to Vue component. Let it be function has to be invoked by @click
. But for some reasons I want to keep default behaviour for the component. The default behaviour is not so easy as I want and I'm going to use method
as default function. Because the default behaviour requires data from component's state (props, data, other methods, whatever).
Is there a way to do?
I've attached the example. Expected behaviour:
Button works fine
should produce alert You are welcome!
Button nope
should produce alert You are welcome as well!
but does nothing.
Vue.component('welcome-component', {
template: '#welcome-component',
props: {
name: {
type: String,
required: true,
},
action: {
type: Function,
required: false,
default: () => { this.innerMethod() },
},
},
methods: {
innerMethod() {
alert("You are welcome as well!");
}
}
});
var app = new Vue({
el: "#app",
methods: {
externalMethod() {
alert("You are welcome!");
}
}
});
#app {
margin: 20px;
}
.holder > button {
margin: 10px;
padding: 5px;
font-size: 1.1em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<welcome-component name="works fine" :action="externalMethod"></welcome-component>
<welcome-component name="nope"></welcome-component>
</div>
<script id='welcome-component' type='x-template'>
<div class="holder">
<button @click="action">{{ name }}</button>
</div>
</script>
You can pass strings, arrays, numbers, and objects as props. But can you pass a function as a prop? While you can pass a function as a prop, this is almost always a bad idea. Instead, there is probably a feature of Vue that is designed exactly to solve your problem.
To pass a component as props and use it in a child component in Vue. js, we can use the component component. to add the component component. We set the is prop to the childComponent string which has the name of the component we want to render.
All props are optional by default, unless required: true is specified. An absent optional prop other than Boolean will have undefined value. The Boolean absent props will be cast to false .
From vue docs:
"Note that props are validated before a component instance is created, so instance properties (e.g. data, computed, etc) will not be available inside default or validator functions."
(https://v2.vuejs.org/v2/guide/components-props.html)
Referencing the innerMethod
is therefore one of the cases where the components function is not yet available.
Idea: If it is crucial for you to have this kind of functionality you could check within a later lifecycle hook (like created, mounted etc.) whether the type of action
is function
. If it's not a function (meaning not passed via prop), assign the innerMethod manually.
This works but it's a total bag of spanners:
action: {
required: false,
default () {
return () => this.innerMethod();
},
},
I've had to remove the type: Function
. Usually when default
is a function it will be invoked to return the appropriate default value. However, if the prop has type: Function
it'll just treat the function as the default. In this case that's problematic because we lose the this
binding.
The internal arrow function is required to get around the problem that the methods aren't available when the default
function is called.
If possible I would suggest giving up on using a default
and instead just apply the 'default' when it needs to be invoked. So rather than calling action
directly in the click
handler, instead call a method called invokeAction
that looks something like this:
invokeAction () {
if (this.action) {
this.action();
} else {
this.innerMethod();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With