在另一个道具的验证器中访问道具值

时间:2019-07-05 13:47:58

标签: vue.js vuejs2 vue-component

我想在另一个道具的验证器中访问一个道具值:

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。 有想法吗?

3 个答案:

答案 0 :(得分:0)

道具的this中的validator变量未引用Vue实例。而且,不幸的是,没有一种真正的方法可以在道具的validator函数中引用另一个道具的值。


您可以做的一件事是在Vue实例的$props对象上设置观察者,将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>


另一种选择是将具有typesize属性的对象作为单个道具传递。这样,该道具的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。我在示例中将该逻辑更新为我认为的含义。)

答案 1 :(得分:0)

不可能。 VUE项目中的提议很少,但都被拒绝了:

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

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

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

这种情况的简单方法是使用计算的属性或验证created钩上的属性。在这种情况下,所有属性均可用。

答案 2 :(得分:0)

如果您只需要验证一次,则只需在mount()处理程序中进行即可。这使我们的笑话测试失败了,并在浏览器中记录了一个错误。

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