daiwei hai 1 ano
pai
achega
783d60a4d0

+ 6 - 6
packages/compiler-core/__tests__/transforms/__snapshots__/vMemo.spec.ts.snap

@@ -7,12 +7,12 @@ export function render(_ctx, _cache) {
   return (_openBlock(), _createElementBlock("div", null, [
     (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.tableData, (data, _key, ___, _cached) => {
       const _memo = (_ctx.getLetter(data))
-      if (_cached && _cached.key === _ctx.getId(data) && _isMemoSame(_cached, _memo)) return _cached
+      if (_cached && _cached.el && _cached.key === _ctx.getId(data) && _isMemoSame(_cached, _memo)) return _cached
       const _item = (_openBlock(), _createElementBlock("span", {
         key: _ctx.getId(data)
       }))
       _item.memo = _memo
-      _item.cacheIndex = _key
+      _item.cacheIndex = [0, _key]
       return _item
     }, _cache, 0), 128 /* KEYED_FRAGMENT */))
   ]))
@@ -56,10 +56,10 @@ export function render(_ctx, _cache) {
   return (_openBlock(), _createElementBlock("div", null, [
     (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.list, ({ x, y }, _key, ___, _cached) => {
       const _memo = ([x, y === _ctx.z])
-      if (_cached && _cached.key === x && _isMemoSame(_cached, _memo)) return _cached
+      if (_cached && _cached.el && _cached.key === x && _isMemoSame(_cached, _memo)) return _cached
       const _item = (_openBlock(), _createElementBlock("span", { key: x }, "foobar"))
       _item.memo = _memo
-      _item.cacheIndex = _key
+      _item.cacheIndex = [0, _key]
       return _item
     }, _cache, 0), 128 /* KEYED_FRAGMENT */))
   ]))
@@ -73,12 +73,12 @@ export function render(_ctx, _cache) {
   return (_openBlock(), _createElementBlock("div", null, [
     (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.list, ({ x, y }, _key, ___, _cached) => {
       const _memo = ([x, y === _ctx.z])
-      if (_cached && _cached.key === x && _isMemoSame(_cached, _memo)) return _cached
+      if (_cached && _cached.el && _cached.key === x && _isMemoSame(_cached, _memo)) return _cached
       const _item = (_openBlock(), _createElementBlock("div", { key: x }, [
         _createElementVNode("span", null, "foobar")
       ]))
       _item.memo = _memo
-      _item.cacheIndex = _key
+      _item.cacheIndex = [0, _key]
       return _item
     }, _cache, 0), 128 /* KEYED_FRAGMENT */))
   ]))

+ 4 - 2
packages/compiler-core/src/transforms/vFor.ts

@@ -227,7 +227,7 @@ export const transformFor: NodeTransform = createStructuralDirectiveTransform(
           loop.body = createBlockStatement([
             createCompoundExpression([`const _memo = (`, memo.exp!, `)`]),
             createCompoundExpression([
-              `if (_cached`,
+              `if (_cached && _cached.el`,
               ...(keyExp ? [` && _cached.key === `, keyExp] : []),
               ` && ${context.helperString(
                 IS_MEMO_SAME,
@@ -235,7 +235,9 @@ export const transformFor: NodeTransform = createStructuralDirectiveTransform(
             ]),
             createCompoundExpression([`const _item = `, childBlock as any]),
             createSimpleExpression(`_item.memo = _memo`),
-            createSimpleExpression(`_item.cacheIndex = _key`),
+            createSimpleExpression(
+              `_item.cacheIndex = [${context.cached.length}, _key]`,
+            ),
             createSimpleExpression(`return _item`),
           ])
           renderExp.arguments.push(

+ 9 - 1
packages/runtime-core/src/renderer.ts

@@ -2097,7 +2097,15 @@ function baseCreateRenderer(
 
     // #6593 should clean memo cache when unmount
     if (cacheIndex != null) {
-      parentComponent!.renderCache[cacheIndex] = undefined
+      if (isArray(cacheIndex)) {
+        const [parentIndex, itemIndex] = cacheIndex
+        const parentCache = parentComponent!.renderCache[
+          parentIndex
+        ]! as unknown as VNode[]
+        parentCache[itemIndex].el = null
+      } else {
+        parentComponent!.renderCache[cacheIndex] = undefined
+      }
     }
 
     if (shapeFlag & ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE) {

+ 2 - 1
packages/runtime-core/src/vnode.ts

@@ -243,8 +243,9 @@ export interface VNode<
   memo?: any[]
   /**
    * @internal index for cleaning v-memo cache
+   * cacheIndex will be an array when vnode in vFor
    */
-  cacheIndex?: number
+  cacheIndex?: number | number[]
   /**
    * @internal __COMPAT__ only
    */