Closed ArkIv closed 3 years ago
Thank you for creating an issue!
I am not completely sure what is the case where you need a default value of the prop to be reactive. It's only used as a fallback in the case if you didn't pass any value from the parent component, and you're not supposed to mutate a prop (or its default value) from the child component. Could you please explain why do you need prop default value to be reactive?
It is very convenient to work with one object without copying it to add property changes, And even in combination with provide (). Generally after default: () => { return reactive ([{xxxx}, {yyy}, {. . .}]) The object, as it were, ceases to be Default, it is used only in this component and only in this. And for another component, Default will be clean and unchanged again, For a component, I can have an object uploaded via ajax as well as by default. And if it is assumed that the props received via data can be reactive, Then why not make it reactive by default as well. Well, or at least mention that it doesn't work that way.
We do not recommend mutating props object in the child component as it breaks Vue unidirectional dataflow 🤔 Changes should happen in the component where you pass a prop and this should efficiently override a default value.
This isn't specific to the default
. In general the values of props
are not made reactive. They'll only be reactive if the value passed by the parent was already reactive.
The same is true of objects returned by computed
properties. The property itself is reactive but the value is not. Again, if the object returned is already reactive then the reactivity is not stripped.
I've put together a little example to demonstrate some of these cases:
https://jsfiddle.net/skirtle/3ty4dkc6/
This shallow reactivity is by design. There is an expectation that such objects shouldn't be mutated and any changes need to be made to upstream reactive data instead.
The object, as it were, ceases to be Default, it is used only in this component and only in this. And for another component, Default will be clean and unchanged again,
That's true. To some extent you could view the current component as the owner for that particular object and argue that it is fine to edit it. However, there are a couple of problems with that way of looking at it:
However, all that said, there is a legitimate question about what we can add to the documentation to make this clearer. There is a difficult line to tread, including explanations for all the edge cases while not confusing the reader with too much information. Historically, statements like 'methods are not reactive' have led to a lot of confusion and the scenario described here is similar. It's really difficult to explain what such statements really mean without losing the reader.
Thanks for the detailed answer. And in the documentation (props), just add that the default will not be not reactive. It may be confusing that we do not specify in Data reactive.
Considering @skirtles-code point about complicated explanation and my own comments about how props default
value is used, I don't think we need to add this to documentation. As I've mentioned above, you shouldn't override props default value from the child component (thus you don't need a reactivity), and when you pass a value from the parent component, default
will be overridden by the actual value and will be reactive/non-reactive depending on what parent component passes down.
The reactivity of the default 'Object' type attribute is lost, or not created.
====>
Found nowhere in the documentation . I had to do so, but what should be done correctly?
Data automatically makes components reactive, But somehow illogical, the data are the same Props, But does not make them reactive although props itself is reactive, If I had not installed default, I would not have noticed this and would never have known.
Add to documentation, at least here https://v3.vuejs.org/guide/component-props.html#prop-validation // Object or array defaults must be returned from // a factory function not reactive, use reactive()
@vue/cli 4.5.8