I want to access a props value in another props' validator:
props: {
type: {
type: String,
default: "standard"
},
size: {
type: String,
default: "normal",
validator(value) {
// below I want to access the props `type` from above.
return (this.type !== "caution" || this.type !== "primary") && value !== "mega"
}
}
}
But I'm getting TypeError: Cannot read property 'type' of undefined
.
Any idea?
The this
variable in a prop's validator
does not reference the Vue instance. And, unfortunately, there's no real way to reference another prop's value in a prop's validator
function.
One thing you could do would be to set a watcher on the Vue instance's $props
object, setting the immediate
option to true
so that the watcher fires when the component is created. That watcher could trigger the validation logic where this
is a reference to the Vue instance.
Here's a simple example:
Vue.config.productionTip = false;
Vue.config.devtools = false;
Vue.component('child', {
template: '<div></div>',
props: {
type: {
type: String,
default: "standard"
},
size: {
type: String,
default: "normal"
}
},
methods: {
validateProps() {
if ((this.type === "caution" || this.type === "primary") && this.size === "mega") {
console.error('Invalid props');
}
}
},
watch: {
$props: {
immediate: true,
handler() {
this.validateProps();
}
}
}
});
new Vue({
el: '#app'
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<child type="caution" size="mega"></child>
</div>
Another option would be to pass an object with a type
and size
property as a single prop. That way the validator
of that prop would have a reference to both values.
Vue.config.productionTip = false;
Vue.config.devtools = false;
Vue.component('child', {
template: '<div></div>',
props: {
config: {
type: Object,
default: () => ({ type: "standard", size: "normal" }),
validator({ type, size }) {
return !((type === "caution" || type === "primary") && size === "mega");
}
}
}
});
new Vue({
el: '#app'
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<child :config="{ type: 'caution', size: 'mega'}"></child>
</div>
(And just a note: your validation logic is probably incorrect. As it's written, the statement in parenthesis will always evaluate to true
. I updated that logic in my examples to be what I think you meant.)
If you only need to validate once, do it simply in the mounted() handler. This fails the jest tests for us, and logs an error in the browser.
props: {
type: {
type: String,
default: "standard"
},
size: {
type: String,
default: "normal"
}
},
mounted() {
if ((this.type === "caution" || this.type === "primary") && this.size === "mega") {
console.error('Invalid props');
}
}
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