v-memo on child of v-for does not render or updates properly
Version
3.2.0-beta.7
Reproduction link
Steps to reproduce
open the Reproduction link click on inc button, every 5 clicks the memo should trigger an update
there are 2 lists.
- the first one the
v-memo
is on the child element - the 2nd list the
v-memo
is on the element with thev-for
.
in the second list all items will update when the memo dependency changes. in the first list, there are 2 problems.
- only the last item gets updated.
- the props passed to the component all render as 0 in all items. ( except for odd values on the last item in the list)
What is expected?
2nd list should probably render the same as 1st list
What is actually happening?
inconsistent render with missing values of props
This is not correct usage:
- flip is not even reactive
- flip isn't used in the subtree where memo is placed
It's great you're playing around with the API and trying to report back bugs but as said in the PR, if you think memo could be used in other scenarios, described those scenarios first instead of showing abstract cases that are not realistic and are not what memo is trying to solve either
in the example the count
increment is what triggers the component update.
forcing the reevaluation of the memo to check if the value changes since last render
Memoize a sub-tree of the template. Can be used on both elements and components. The directive expects a fixed-length array of dependency values to compare for the memoization. If every value in the array was the same as last render, then updates for the entire sub-tree will be skipped. For example:
- no where in the docs it is indicated that flip has to be reactive.
- using flip in the subtree reactive or not makes no difference
also a minimal reproduction of a problem should not reflect a business problem or a use case, it sufficient to show that there is a problem in the most simplistic way for developers to find or identify the bug.
there are 2 v-for list that seemingly should have behaved the same and they are not, this is indicative of a bug.
Thanks for the repro. I actually misread this issue, the different behavior is indeed a bug.
no where in the docs it is indicated that flip has to be reactive
There are: non-reactive variable changes don't trigger template updates in general. In this case, it makes no difference because other variables are triggering a template update but if there are none, you won't see any updates (click 5 times to see no changes)
(
+ because we disable tracking the block tree here.
_openBlock(true),
_createElementBlock(_Fragment, null, _renderList(_unref(items), (id, index, ___, _cached) => {
const _memo = ([ _unref(flip) ])
+ here currentBlock is null, As a result, the block tree is not tracked correncly in isMemoSame.
if (_cached && _cached.key === id && _isMemoSame(_cached, _memo)) return _cached
const _item = (_openBlock(), _createBlock(Item, {
count: count.value,
index: index,
key: id
}, null, 8 /* PROPS */, ["count", "index"]))
_item.memo = _memo
return _item
}, _cache, 1), 128 /* KEYED_FRAGMENT */))
Ok, this is not a bug, but this is currently by design: v-memo
does not work inside v-for
, it can only be used with v-for
(on the same element). Could probably be improved though.
From the user's point, maybe add this into syntax/context checker of Vue compiler?
As mentioned above, for current state, v-memo
cannot be inside v-for
".
Update:
Ops.. I just find out that eslint-plugin-vue
can check this issue, vue/valid-v-memo