Access props value in another props' validator

陌路散爱 提交于 2021-01-26 04:42:10

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!