问题
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?
回答1:
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.)
回答2:
It is not possible. There were few propositions in VUE project but all were rejected:
https://github.com/vuejs/vue/issues/3495
https://github.com/vuejs/vue/issues/6787
https://github.com/vuejs/vue/issues/9925
The trivial way for such case is to use a computed property or to validate properties on created
hook. In this case, all properties are available.
回答3:
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');
}
}
来源:https://stackoverflow.com/questions/56904327/access-props-value-in-another-props-validator