Access props value in another props' validator

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');
  }
}

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