You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Problem with literal object props in template #4060
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.
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?
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.
Expression like :prop="'nested "quote"'" is not supported.
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?
The use case is not clear to me. The example is just changing the number until it reaches 100
If we introduce the warning, what will it check? Using object literals is quite usual for class and style bindings. If we warn the user about that, we're kind of forcing him to fix it because nobody wants to leave a warning on their console 😛
I think it's good to tell the user to use a computed property instead but wanted to point out that
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.
Reacted by Eduardo San Martin Morote, Daniel Diekmeier, R-Yin and Mark Fisher
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 literal keyword, and I only got two results (1/2), one of which even give an example of using object literals:
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 .once modifier was removed in Vue 2.x. I don't think this modifier breaks one-way binding. On the contrary, I think it will be helpful in Vue 2.x to perform a static prop. So any idea of bringing it back? @yyx990803
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.
Activity
paulpflug commentedon Oct 29, 2016
The problem is within your watch..
You can do two things:
fnlctrl commentedon Oct 30, 2016
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
chrisvfritz commentedon Oct 31, 2016
@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?
fnlctrl commentedon Oct 31, 2016
@chrisvfritz Hmm that seems possible, but I'm not familiar with the template compiler.. @defcc any ideas?
HerringtonDarkholme commentedon Oct 31, 2016
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
:prop="'nested "quote"'"is not supported.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?
defcc commentedon Oct 31, 2016
I think there is no need to cache the literals just for the misusage of binding props,maybe we could introduce a warning instead when parsing in dev mode ?
posva commentedon Oct 31, 2016
The use case is not clear to me. The example is just changing the number until it reaches 100
If we introduce the warning, what will it check? Using object literals is quite usual for class and style bindings. If we warn the user about that, we're kind of forcing him to fix it because nobody wants to leave a warning on their console 😛
I think it's good to tell the user to use a computed property instead but wanted to point out that
defcc commentedon Oct 31, 2016
Means non-dynamic value, not just object literals :)
for example
:arr="[1]" :obj="{}" :id="1"chrisvfritz commentedon Oct 31, 2016
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.
yyx990803 commentedon Nov 1, 2016
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).
coolzjy commentedon Nov 6, 2016
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
literalkeyword, and I only got two results (1/2), one of which even give an example of using object literals: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
.oncemodifier was removed in Vue 2.x. I don't think this modifier breaks one-way binding. On the contrary, I think it will be helpful in Vue 2.x to perform a static prop. So any idea of bringing it back? @yyx990803Noemi- commentedon Jun 3, 2019
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.
chandanwtb commentedon Sep 20, 2020
When I am using

format: 'DD/MM/YYYY', Calendar is working fine but whenformat: 'DD/MM/YYYY h:mm:ss'Calendar is Not working.But When format:
'DD/MM/YYYY'danielgindi commentedon Feb 1, 2022
Just bit me in the behind too. The vue eslint plugin should detect this.