127

This error got me when passing different values to the component.

enter image description here

Harsha Basnayake
  • 4,565
  • 3
  • 17
  • 23

4 Answers4

262

Here is the solution I found.

props: {
   value: [Number, String, Array]
}
NerV
  • 51
  • 1
  • 1
  • 9
Harsha Basnayake
  • 4,565
  • 3
  • 17
  • 23
  • 5
    If you don't care about the type, you don't have to specify it. Of course if you expect these three kinds, it's good to explicit state them. – Kordonme Dec 04 '18 at 08:19
  • 6
    Using the first solution, eslint gives me an error: `The "value" property should be a constructor (vue/require-prop-type-constructor)`. The second solution produces no errors or warnings – 735Tesla Jun 13 '19 at 16:17
  • 1
    Can I define multiple types along with required string? like below `order: { type: [Object, null], required: true }` because this throws error for me. – Samiullah Khan Jul 16 '19 at 06:52
  • 6
    The first proposed solution with pipe char - that can't possibly work, since pipe char is XOR operation, and the result of `Number XOR String` is 0. So basically, you set `value : 0`. My guess is vuejs just ignores the type if value is zero, so it _appears_ that it works, but it actually works always regardless of the acutally passed value. – Mārtiņš Briedis Oct 09 '19 at 10:05
72

The syntax with a pipe (Number | String), like proposed in the accepted answer, does not actually work. Here is a more detailed solution with examples:

Type-Check, Not Required Prop

Use of the following syntax to type check a prop:

props: {
  username: {
    type: [ String, Number ]
  }
}

Here is a live example of a property with type check:

Vue.config.devtools = false;
Vue.config.productionTip = false;

Vue.component('test-component', {
  name: 'TestComponent',
  props: {
    username: {
      type: [ String, Number ]
    }
  },
  template: `<div>username: {{ username }}</div>`
});

new Vue({ el: '#app' });
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.js"></script>

<div id="app">
  <!-- valid: String -->
  <test-component :username="'user 38'"></test-component>
  
  <!-- valid: Number -->
  <test-component :username="59"></test-component>
  
  <!-- valid: null is valid, it is not required -->
  <test-component :username="null"></test-component>

  <!-- valid: missing property is valid, it is not required -->
  <test-component></test-component>

  <!-- invalid: Array -->
  <test-component :username="['test', 456]"></test-component>
</div>

Type-Check, Required Prop & Custom Validator

Use the following syntax to type check a required property together with a custom validator.

props: {
  username: {
    type: [ String, Number ],
    required: true, // optional
    validator: item => item !== '123' // optional
  }
}

Here is a live example of a required property together with a custom validator:

Vue.config.devtools = false;
Vue.config.productionTip = false;

Vue.component('test-component', {
  name: 'TestComponent',
  props: {
    username: {
      type: [ String, Number ],
      required: true,
      validator: item => item !== '123'
    }
  },
  template: `<div>username: {{ username }}</div>`
});

new Vue({ el: '#app' });
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.js"></script>

<div id="app">
  <!-- valid: String -->
  <test-component :username="'user 38'"></test-component>
  
  <!-- valid: Number -->
  <test-component :username="59"></test-component>
  
  <!-- invalid: Array -->
  <test-component :username="['test', 456]"></test-component>
  
  <!-- invalid: String, but disallowed by custom validator -->
  <test-component :username="'123'"></test-component>
  
  <!-- invalid: null property, it is required though -->
  <test-component :username="null"></test-component>

  <!-- invalid: missing required prop -->
  <test-component></test-component>
</div>
ssc-hrep3
  • 15,024
  • 7
  • 48
  • 87
8

In general props listed as an array of strings, if you don't have any headache of type:

props: ['title', 'likes', 'isPublished', 'commentIds', 'author']

If you want every prop to be a specific type of value. In these cases, you can list props as an object, where the properties’ names and values contain the prop names and types, respectively:

props: {
    title: String,
    likes: Number,
    isPublished: Boolean,
    commentIds: Array,
    author: Object
}

If you want to use multiple type then as follows:

props: {
    value: [String, Number],
}
Md Riadul Islam
  • 1,273
  • 11
  • 25
4

As others suggested there are two ways to define props in vuejs:

The first one

//No need to define the type with this one
props: ['myVariable', 'foo', 'something']

The second one

//With this one you can define what type the prop is and other different useful things!
props: {
  myVariable: String, //You can define the type like this
  anyOfTheFollowing: String/Object/Array, //You can also define multiple possible types
  'kebab-case-like': Function, //Since vuejs is still javascript and the property 'props' is actually an object, you can define your props like this for kebab-case. You can also just use camelCase and use the kebab-case version in your template and it will still recognize it
  customOne: MyCustomType, //You can in theory use classes you've defined aswell
  foo: { //This is another way of defining props. Like an object
    type: Number,
    default: 1, //This is why this is mostly used, so you can easily define a default value for your prop in case it isn't defined
  },
  andAnotherOne: {
    type: Array,
    default: () => [], //With Arrays, Objects and Functions you have to return defaults like this since you need to return a new reference to it for it to be used
  },
  requiredOne: {
    type: Object,
    required: true //Another use for this. When it is marked as required and it isn't defined you'll get an error in the console telling you about it
  }
}

IMO I love the second version since it opens to so much more and I particularly like the default property the most.

Jasqui
  • 391
  • 2
  • 5