-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Problem with literal object props in template #4060
Comments
The problem is within your watch.. watch: {
prop: function(val,oldVal) {
// val will be {}
// oldVal will be {}, too, but another instance, so they are not equal
}
} You can do two things:
|
Using object literals in template as prop should indeed be warned against, since in 2.0 it means creating a new object every time the component updates... Though I can't seem to think of a way to detect it at runtime. Maybe we can add a warning in the docs? @chrisvfritz |
@fnlctrl When parsing the template, could we add object/array literals to a component instance-scoped cache, so that their reference remained the same between updates? |
@chrisvfritz Hmm that seems possible, but I'm not familiar with the template compiler.. @defcc any ideas? |
Seems impossible because Vue's parse is a simple regex scanner + recursive descendant parser, optimized for payload size. No real javascript expression parser is included. Source: https://github.com/vuejs/vue/blob/dev/src/compiler/parser/html-parser.js#L16 and https://github.com/vuejs/vue/blob/dev/src/compiler/parser/html-parser.js#L196 Expression like IMHO, adding a warning in the doc is probably enough for now. For longer term, I think this check is better integrated in vue-template-validator or so? |
maybe we could introduce a warning instead when parsing in dev mode ? |
The use case is not clear to me. The example is just changing the number until it reaches 100 |
Means non-dynamic value, not just object literals :) for example :arr="[1]" :obj="{}" :id="1" |
I think only objects and arrays are a problem though, because those are pass by reference in JS. Strings, numbers, and booleans are all immutable, so equal values will always share the same reference. Either way, I'd like to avoid adding notes like this to the docs - even if we don't fix it. Not only is this an edge case, but the resulting behavior has nothing to do with Vue specifically, but would be the expected behavior for any JS lib with render functions. |
I don't think there is a way to prevent what is happening in the original fiddle - it's expected behavior given how 2.0's render system works. As for warning literal object/arrays, the tricky thing is it could be valid usage as long as the user doesn't attempt to mutate the value (which I believe is already warned against in the docs). |
I'm also encountered this problem in my code, and I spend lots of time debugging without help of warning. I also search the docs for <div v-demo="{ color: 'white', text: 'hello!' }"></div> I think static prop is useful under many conditions. Static props' action in Vue 1.x is in line with expectations, but a little confusing in Vue 2.x (although I know how it works). I also noticed that |
I encountered this as well, when I try to bind an Array literal to a component's property. It spend me half day to realize that it is a "render function + Array literal property" issue, through several experiments and debug. |
Just bit me in the behind too. The vue eslint plugin should detect this. |
Vue.js version
2.0.3
Reproduction Link
http://codepen.io/KathyMiao/pen/XjLJxE?editors=1010
Steps to reproduce
When the template has literal object props, it may cause template re-render.
What is Expected?
number:1
What is actually happening?
number:100
This usage is very common with vue 1.x. However, it causes problem in vue 2.x with no warning and recommendation. It is not easy to debug and find out the cause. Warning message and usage description in vue guide will be helpful.
The text was updated successfully, but these errors were encountered: