Доступ к значению реквизита в валидаторе другого реквизита - PullRequest
1 голос
/ 05 июля 2019

Я хочу получить доступ к значению реквизита в валидаторе другого реквизита:

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"
    }
  }
}

Но я получаю TypeError: Cannot read property 'type' of undefined.Есть идеи?

Ответы [ 2 ]

0 голосов
/ 05 июля 2019

Это невозможно. В проекте VUE было мало предложений, но все они были отклонены:

https://github.com/vuejs/vue/issues/3495

https://github.com/vuejs/vue/issues/6787

https://github.com/vuejs/vue/issues/9925

Тривиальным способом для такого случая является использование вычисляемого свойства или проверка свойств на хуке created. В этом случае все свойства доступны.

0 голосов
/ 05 июля 2019

Переменная this в реквизите validator не ссылается на экземпляр Vue. И, к сожалению, нет реального способа ссылаться на значение другого пропа в функции validator пропа.


Единственное, что вы можете сделать, это установить наблюдатель на объект $props экземпляра Vue, установив для параметра immediate значение true, чтобы наблюдатель срабатывал при создании компонента. Этот наблюдатель может вызвать логику проверки, где this является ссылкой на экземпляр Vue.

Вот простой пример:

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>

Другой вариант - передать объект со свойствами type и size в качестве одного реквизита. Таким образом, validator этой опоры будет иметь ссылку на оба значения.

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>

(И просто примечание: ваша логика проверки, вероятно, неверна. Как написано, выражение в скобках всегда будет иметь значение true. Я обновил эту логику в своих примерах, чтобы она соответствовала тому, что, я думаю, вы имели в виду.)

...