vue 在 template 标签 中嵌套for循环 ,动态更新的情况下 key值 避坑

198 阅读1分钟

爆错信息

vue.1aed1ac9.dll.js:15 TypeError: Cannot read properties of undefined (reading 'key')
    at Po (vue.1aed1ac9.dll.js:15:51583)
    at vue.1aed1ac9.dll.js:15:70144
    at C (vue.1aed1ac9.dll.js:15:70306)
    at vue.1aed1ac9.dll.js:15:69831
    at C (vue.1aed1ac9.dll.js:15:70306)
    at a.__patch__ (vue.1aed1ac9.dll.js:15:71441)
    at t._update (vue.1aed1ac9.dll.js:15:43724)
    at a.r (vue.1aed1ac9.dll.js:15:78728)
    at t.get (vue.1aed1ac9.dll.js:15:27051)
    at t.run (vue.1aed1ac9.dll.js:15:27784)

image.png

代码如下,注意第一次的for循环是写在 template 里面的,并且拥有子级的for循环,这段代码在renderListData更新之后会爆key值问题的错

<div v-if="renderListData.length > 0" class="export-tab-content">
    <div class="checkout-box">
      <el-checkbox
        :value="checkAllMenu"
        class="checkAllComp"
        :disabled="
          (['update', 'install', 'export'].includes(type) &&
            contentType != 'pkgDevelopmentKitInfos') ||
            isDisabledAllCheckout
        "
        @change="handleCheckAllChange"
      >
        {{ $t('component.exportAppTabs.checkAll') }}
      </el-checkbox>
    </div>

    <template v-for="(item, index) in renderListData">
      <div v-if="item.state !== 'UNCHANGED' || !isFilterNoChange" :key="index">
        <export-menu-item
          :contentType="contentType"
          :renderNameMap="renderNameMap"
          :menuData="item"
          :disabled="
            (['update', 'install', 'export'].includes(type) &&
              contentType != 'pkgDevelopmentKitInfos') ||
              (contentType === 'appMenuList' &&
                item.subMenuInfos &&
                item.subMenuInfos.length > 0) ||
              contentType === 'dataModelList' ||
              item.isDisabled
          "
          @handleCheckItem="handleCheckItem"
        ></export-menu-item>
      </div>
      <template v-if="item.subMenuInfos && (item.state !== 'UNCHANGED' || !isFilterNoChange)">
        <div v-for="(childItem, childItemIndex) in item.subMenuInfos" :key="childItemIndex" class="children-item">
          <template v-if="childItem.state !== 'UNCHANGED' || !isFilterNoChange">
            <export-menu-item
              :contentType="contentType"
              :renderNameMap="renderNameMap"
              :menuData="childItem"
              :parentMenuData="item"
              :disabled="
                ['update', 'install', 'export'].includes(type) ||
                  (contentType === 'appMenuList' &&
                    childItem.subMenuInfos &&
                    childItem.subMenuInfos.length > 0)
              "
              menuType="children"
              @handleCheckItem="handleCheckItem"
            ></export-menu-item>
          </template>
        </div>
      </template>
    </template>
  </div>

解决:别用template模板做for循环