props input an object and behave inconsistently in production and development mode.
Vue version
3.2.37
Link to minimal reproduction
Steps to reproduce
1、Run this demo in development
mode in a local tool.
2、Click on label1
or label2
.
3、Looking at the console log, you will find that the options update is triggered.
4、After compiling, open index.html (or operate directly on the playground) and repeat the second step.
5、Looking at the console log, there is no onTrigger, indicating that the options update is not triggered.
What is expected?
The development mode is the same as the production mode, and options update will not be triggered.
What is actually happening?
The two modes are inconsistent, and the above scenario occurs.
System Info
No response
Any additional comments?
Can you discuss a better solution? At present, this may lead to inconsistencies in the logic of developers in development and production, so that some wrong processing is applied to production.
This is a tricky one as the observed behavior is a compromise we consciously accecpted in order to get better perf in production while having proper updates during HMR in development:
- The compiler is aware that we dynamically generate a fresh array on every render in the template, but also, that it's a static value, meaning it will always come out the same shape.
- Therefore, the compiler tells the renderer that it can effectives skip this prop during updates
- But in dev, for HMR, we always need to send all props to the child component in case that the latest change that triggered HMR changed an (otherwise static) prop.
Making this consistent would mean for us to a) remove the render optimization in prod or b) break HMR, none of which seem like good alternatives (maybe there are others, but I'm not immediately aware of one).
At the same time, we are aware that unexpected behavioral differences between dev and prop can be very problematic and lead to hard-to-trace bugs driving devs insane.
The reason we still made this design choice is that we are under the impression that there's little to no reason to rely on the update of a prop like options
in your example that is, by it's nature, static, and only dynamic because the value was generated in the template, not the script block.
So to better understand the scope of this issue for you, can you give us an example of where you relied on this dev behavior and how it affected your app?
In this demo, clickCounter
will always be 0
in dev
mode. Similar scenarios may be encountered in the development of component libraries and daily business development. Perhaps it is not a counter, but some other initialization or request . It is possible to avoid such dynamic object parameters by specifying development rules, but the user's behavior cannot be restricted on the component library.