Subscribe on changes!

App.vue(parent) variable change <component :is='Children' > ,Children.vue render twice

avatar
Jul 28th 2021

Version

3.1.5

[Reproduction link]

https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHRlbXBsYXRlPlxuICA8ZGl2PlxuICAgIDxzcGFuIHYtdGV4dD1cInZhbFwiPjwvc3Bhbj5cbiAgICA8YnV0dG9uIEBjbGljaz1cInZhbD0nNTY3J1wiPua1i+ivlTwvYnV0dG9uPlxuXG4gICAgPGRpdiA6a2V5PVwiaXRlbS5pZFwiIHYtZm9yPVwiaXRlbSBpbiBhcnJcIj5cblxuICAgICAgPCEtLSAgIGFibm9ybWFsICAgLS0+XG4gICAgICA8Y29tcG9uZW50IDppcz1cIkNoaWxkcmVuXCIgdi1tb2RlbD1cIml0ZW0uaWRcIi8+XG5cbiAgICAgIDwhLS0gICBub3JtYWwgICAtLT5cbiAgICAgIDwhLS0gPGNvbXBvbmVudCA6aXM9XCJBYmNcIiB2LW1vZGVsPVwiYXJyWzBdLmlkXCIvPiAgLS0+XG5cbiAgICA8L2Rpdj5cblxuICA8L2Rpdj5cbjwvdGVtcGxhdGU+XG48c2NyaXB0IGxhbmc9XCJ0c1wiIHNldHVwPlxuaW1wb3J0IHtyZWZ9IGZyb20gJ3Z1ZSc7XG5pbXBvcnQgQ2hpbGRyZW4gZnJvbSAnLi9DaGlsZHJlbi52dWUnXG5cbmNvbnN0IHZhbD1yZWYoJzEyMycpXG5cbmNvbnN0IGFycj1yZWYoW3tpZDonMTEnfV0pXG5cbjwvc2NyaXB0PlxuIiwiQ2hpbGRyZW4udnVlIjoiPHRlbXBsYXRlPlxuICA8ZGl2IDpjY2M9XCJoZWxsbygpXCI+PC9kaXY+XG48L3RlbXBsYXRlPlxuPHNjcmlwdCBsYW5nPVwidHNcIiBzZXR1cD5cbmZ1bmN0aW9uIGhlbGxvKCl7XG4gIGRlYnVnZ2VyXG4gIHJldHVybiAnJ1xufVxuPC9zY3JpcHQ+XG4ifQ==

Steps to reproduce

  1. item in v-for "arr"
  2. App.vue(parent) Irrelevant variable change
  3. watch the devtools,
  4. click button
  5. <result1>:<component v-model='item.id'>,Children.vue render twice
  6. <result2>:<component v-model='arr[0].id'>,Children.vue oneice twice

What is expected?

render onice

What is actually happening?

App.vue(parent) variable change , Children.vue render twice


watch the devtools, click button
<result1>:<component v-model='item.id'>,Children.vue render twice <result2>:<component v-model='arr[0].id'>,Children.vue render oneice

avatar
Jul 28th 2021

your repro link is broken.

avatar
Jul 28th 2021

I update the repro to make more sense. the problem is: click button should not trigger Children re-render.

avatar
Jul 28th 2021

This is expected behavior, because when you bind v-model to item.id, item is a closure variable - so every render a new v-model callback has to be generated (and cannot be cached due to correctness). This causes the child component to re-render.

See compiler output example - notice the first component's callback is not cached because it references item which is a closure variable. The second component's callback can be cached because it doesn't reference item.

Also this has nothing to do with <component :is>.

In 3.2 you can optimize this case by adding v-memo="[item.id]".