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.)