vuejs / vue

This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core
http://v2.vuejs.org
MIT License
207.81k stars 33.67k forks source link

Vue warns about missing required prop that has a default value #7720

Open decademoon opened 6 years ago

decademoon commented 6 years ago

Version

2.5.13

Reproduction link

http://jsfiddle.net/df4Lnuw6/207/

Steps to reproduce

Specify a required prop with a default value:

Vue.component('comp', {
    template: '<div>{{ typeof x }} {{ x }}</div>',
    props: {
        x: {
            type: Number,
            required: true,
            default: 5,
        },
    },
});

Render the component without specifying a value for that prop:

<comp></comp>

What is expected?

The component should render the following without any prop validation errors:

<div>number 5</div>

What is actually happening?

The component renders OK, but warns about missing required prop x.


While it's true that prop x is not specified, since it has a default value, there should be no warning message.

What exactly does required check for? It appears that it checks two things:

  1. The prop should be provided, as in at least <comp :x="..."></comp>.
  2. The prop value should be non-null and non-undefined.

I think in the case where a required prop has a default value, (1) should be relaxed.

Otherwise, how can I enforce a prop to never be null while also providing a default value if the prop value was not provided?

posva commented 6 years ago

TLDR; Maybe we should indeed allow required + default value in this check

By saying the prop is required you expect the user to always provide a value, so making it have a default value defeats the purpose of the prop being required. When you require a prop, it means that you need that information from the user and that there is no way for you to provide a fallback value.

Otherwise, how can I enforce a prop to never be null while also providing a default value if the prop value was not provided?

No, because null and undefined values always skip validation

If you want to take a deeper look at how the prop validation works, you can check https://github.com/vuejs/vue/blob/dev/src/core/util/props.js#L94

After doing some research in past issues, I found this comment

Hmm, yeah so it needs to be more accurate:

  • null indicates the value is explicitly marked as not present and it should remain null.
  • undefined indicates the value is not present and a default value should be used if available.
  • required: true indicates neither null or undefined are allowed (unless a default is used)

I agree this could be confusing, just as the existence of null vs. undefined in the language itself. But the design was trying to stay close to what these values are designed represent in JS, and changing them would be break

decademoon commented 6 years ago

Yeah, currently the issue that is required: true implies that the prop cannot be absent, but then if required: false and the prop value is nully then validation is skipped altogether. There is no way to enforce a prop to be non-nully at all times without required: true and hence prop omission is disallowed.

I also think the docs could be more clear about the precise definition of the required option.

posva commented 6 years ago

~The validation will always be skipped with nully values though.~ The validation will always be skipped with nully values and required: false though. Contributions to docs are always welcome 😄

javoski commented 6 years ago

The validation will always be skipped with nully values though.

It's NOT when required: true was given. http://jsfiddle.net/df4Lnuw6/225/

2018-02-28 7 12 42
decademoon commented 6 years ago

@javoski That's confirmed in this section of code https://github.com/vuejs/vue/blob/cd334070f3b82d3f5892c4999cc290ccd4f56fd8/src/core/util/props.js#L101-L110

posva commented 6 years ago

That's right! it is for undefined that validation is skipped with non-required props

yyx990803 commented 6 years ago

How about a new flag useDefaultForNull

Vue.component('comp', {
    template: '<div>{{ typeof x }} {{ x }}</div>',
    props: {
        x: {
            type: Number,
            default: 5,
            useDefaultForNull: true
        },
    },
});
Kingwl commented 6 years ago

useDefaultForNull is toooooooooooo long
hope to find a keyword only has one word 🌚

pqt commented 6 years ago

useDefaultForNull is toooooooooooo long

It also reads ... awkwardly. Am I the only one who thinks that? Personally I'd go with adding nullable as a type declaration and using that as a flag, but I realize that's a little outside of the typical Vue approach.

verymuch commented 4 years ago

By saying the prop is required you expect the user to always provide a value, so making it have a default value defeats the purpose of the prop being required.

Actually, required: ture and default value are coexisting. If the value is undefined, the default value will apply.

DarioDaF commented 1 year ago

By saying the prop is required you expect the user to always provide a value, so making it have a default value defeats the purpose of the prop being required.

Actually, required: ture and default value are coexisting. If the value is undefined, the default value will apply.

In fact it works as intended, it just warns for no reason (since property IS present cause not null in code being it the default value)

moritz-baecker-integra commented 1 month ago

Is there any new information on this issue? We got the same issue with vue spamming the developer console with "missing prop" even though it has a default. Maybe i understood this wrong and there is a solution for this?