Vue3+elementplus sidebar menu recursively traverses submenus

The submenu originally written in the sidebar was not recursively implemented, resulting in a lot of code and more troublesome modification. So I want to change it to recursive, the code is as follows (using a plug-in that automatically imports components)

NavMenu menu component

<template>
    <!-- menu (with submenus) -->
    <template v-for="(item, index) in menus">

        <el-sub-menu :index="item.id + ''" v-if="item.children & amp; & amp; item.children.length > 0" :key=" item.path">
            <template #title>
                <el-icon>
                    <Icon :icon="item.icon" />
                </el-icon>
                <span>{<!-- -->{ item.name }}</span>
            </template>
            <NavMenu :menus="item.children">
            </NavMenu>
        </el-sub-menu>
        <!-- menu (no submenus) -->
        <el-menu-item :index="item.path" :key="item.id" v-else>
            <el-icon>
                <Icon :icon="item.icon" />
            </el-icon>
            <template #title>
                <span>{<!-- -->{ item.name }}</span>
            </template>
        </el-menu-item>

    </template>
</template>
<script setup>
const props = defineProps(['menus'])
const Icon = (props) => {
    if (props. icon) {
        return h(props.icon)
    }
    return h("span")
}
</script>
<style scoped>
/* menu close arrow style */
    .el-sub-menu :deep(.el-sub-menu__icon-arrow) {
        transform: rotate(-90deg) !important;
    }

    /*menu expansion arrow style*/
    .el-sub-menu.is-opened> :deep(.el-sub-menu__title .el-sub-menu__icon-arrow) {
        transform: rotate(0deg) !important;
    }

.el-menu .is-opened> :deep(.el-sub-menu__title) {
    color: #3471FF;
}

/* The style of the sidebar collapsed */
/* .el-menu --collapse {
    display: none;
} */

/* hide the arrow */
/* .el-menu--collapse .el-sub-menu__title .el-sub-menu__icon-arrow {
  display: none;
} */
/* hide text */
/* .el-menu--collapse .el-sub-menu__title span {
  display: none;
} */
</style>

sidebar body

<template>
  <div style="height: 53.125rem;">
    <el-menu :collapse="isCollapse" :unique-opened="true" active-color="#3471FF" router>
      <!-- menu component, recursive -->
      <NavMenu :menus="menus"></NavMenu>

      <!-- Collapse -->
      <el-menu-item @click="isCollapse = !isCollapse" index>
        <el-icon>
          <Icon :icon="IconIndent" v-if="isCollapse" />
          <Icon :icon="IconDedent" v-else />
        </el-icon>
        <span>Collapse navigation</span>
      </el-menu-item>

    </el-menu>
  </div>
</template>

<script setup>
import menus from "./menus.js"
import IconDedent from "~icons/fa/dedent"
import IconIndent from "~icons/fa/indent"

const Icon = (props) => {
  if (props. icon) {
    return h(props.icon)
  }
  return h("span")
}

const isCollapse = ref(false)
const screenWidth = ref(window. innerWidth)
const handleResize = () => {
  screenWidth.value = window.innerWidth
}

onMounted(() => {
  window. addEventListener("resize", handleResize)
})

//watch monitors changes in screen width, and shrinks and expands the sidebar
watch(screenWidth, (newValue, oldValue) => {
  if (newValue < 992) {
    isCollapse. value = true
  } else {
    isCollapse. value = false
  }
})
</script>

<style scoped>
/* Remove the vertical lines from the sidebar */
.el-menu {
  border-right: 0;
}
</style>

Just look at the data of the menu in general, I have written a lot of data

import IconDashboard from "~icons/fa/dashboard"
import IconYen_sign from "~icons/fa-solid/yen-sign"
import Iconpencil_square from "~icons/fa/pencil-square"
import IconShare_alt_square from "~icons/fa/share-alt-square"
import IconClock from "~icons/fa-solid/clock"
import IconLink from "~icons/fa-solid/link"
import IconCalculator from "~icons/fa/calculator"
import IconCog from "~icons/fa/cog"
import IconChain from "~icons/fa/chain"
import IconBar_chart from "~icons/fa/bar-chart"
import IconBitbucket_square from "~icons/fa/bitbucket-square"
import IconSitemap from "~icons/fa-solid/sitemap"
import IconFolder from "~icons/fa-solid/folder"
import IconFolder_minus from "~icons/fa-solid/folder-minus"
import IconSync from "~icons/fa-solid/sync"
import IconUndo_alt from "~icons/fa-solid/undo-alt"
import IconUndo from "~icons/fa-solid/undo"
import IconExchange from "~icons/fa-solid/exchange-alt"
import IconWindow_close from "~icons/fa-solid/window-close"

export default [
  {
    name: "Personal Center",
    id: "0",
    icon: IconDashboard,
    path: "/home",
  },
  {
    name: "Mold Change Price Adjustment",
    id: "1",
    icon: IconYen_sign,
    children: [
      {
        name: "submission details",
        id: "1-1",
        path: "/hdyMoldSubmitLevel1",
      },
      {
        name: "Mold Information Table",
        id: "1-2",
        path: "/hdyModeInfo",
      },
      {
        name: "Mold module number relationship table",
        id: "1-3",
        path: "/hdyMoldMaterialRelationship",
      },
      {
        name: "Calculation Details",
        id: "1-4",
        path: "/hdyMoldComputationDetail",
      },
    ],
  },
  {
    name: "HDY Interaction Results",
    id: "2",
    icon: IconExchange,
    children: [
      {
        name: "HDY price into the system",
        id: "2-1",
        path: "/hdyPriceEntrySystem",
      },
      {
        name: "HDY quota into the system",
        id: "2-2",
        path: "/hdyQuoteEntrySystem",
      },
      {
        name: "HDY bid price into the system",
        id: "2-3",
        path: "/hdyBidPriceEntrySystem",
      },
    ],
  },
  {
    name: "resource replacement result",
    id: "3",
    icon: IconSync,
    children: [
      {
        name: "Successful bidder price entry system",
        id: "3-1",
        path: "/ebsPriceEntrySystem",
      },
      {
        name: "Winning bid price enters the system",
        id: "3-2",
        path: "/ebsBidPriceEntrySystem",
      },
      {
        name: "Quota into the system",
        id: "3-3",
        path: "/ebsQuoteEntrySystem",
      },
    ],
  },
  {
    name: "Price Correction Management",
    id: "4",
    icon: Iconpencil_square,
    children: [
      {
        name: "Different module vendors have different prices for the same material",
        id: "4-1",
        path: "/hdyDifferentPriceDifferenceSameMaterial",
      },
      {
        name: "Same module supplier with same material and different price",
        id: "4-2",
        path: "/hdyDifferentPriceDifferenceSameMaterialtwo",
      },
      {
        name: "The price has not been reduced for a long time",
        id: "4-3",
        path: "/hdyLongTermNoPriceCutOff",
      },
      {
        name: "Haidayuan linkage price difference",
        id: "4-4",
        children: [
          {
            name: "submission details",
            id: "4-4-1",
            path: "/hdyPriceMarginScene",
          },
          {
            name: "Price difference calculation details",
            id: "4-4-2",
            path: "/hdyPriceMarginDetailPriceDiff",
          },
          {
            name: "No price difference calculation details",
            id: "4-4-3",
            path: "/hdyPriceMarginDetailPriceSame",
          },
          {
            name: "Error Log",
            id: "4-4-4",
            path: "/hdyPriceMarginDetailPriceLog",
          },
        ],
      },
      {
        name: "Derivative number price linkage",
        id: "4-5",
        children: [
          {
            name: "The relationship between the derived number and the base number",
            id: "4-5-1",
            path: "/hdyDrivativeBenchmarkRelationship",
          },
          {
            name: "Derivative number linkage display difference details",
            id: "4-5-2",
            path: "/hdyDerivateHome",
          },
          {
            name: "Comparison of the difference between the derivative number and the base number",
            id: "4-5-3",
            path: "/hdyDerivateBenchmarkContrast",
          },
        ],
      },
      {
        name: "Module and component price linkage",
        id: "4-6",
        path: "/hdyBcComponentEntrySystem",
      },
      {
        name: "Derived with same price but different sign",
        id: "4-7",
        children: [
          {
            name: "Correspondence between same price and different sign",
            id: "4-6-1",
            path: "/hdySamePriceDifferentCodeRelationship",
          },
          {
            name: "Same price but different sign difference report",
            id: "4-6-2",
            path: "/hdySamePriceDifferentCodeHome",
          },
        ],
      },
      {
        name: "Multiple price adjustment exception handling",
        id: "4-8",
        path: "/hdyPriceChangeRecord",
      },
      {
        name: "Counter warning",
        id: "4-9",
        path: "/hdySharePricingDetail",
      },
      {
        name: "Purchase and sale BOM change warning",
        id: "4-10",
        path: "/BOMchangewarning",
      },
      {
        name: "Same part with different BOM alarm",
        id: "4-11",
        path: "/hdySamePartsDifferentBOMAlarm",
      },
      {
        name: "Cost reduction mining linkage",
        id: "4-12",
        children: [
          {
            name: "plan management",
            id: "4-12-1",
            path: "/ProcurementPlan",
          },
          {
            name: "Cost reduction entry",
            id: "4-12-2",
            path: "/hdyReduceCostsInputSecond",
          },
          {
            name: "Cost reduction is significantly poor",
            id: "4-12-3",
            path: "/hdyAuthorsShowDifference",
          },
        ],
      },
    ],
  },
  {
    name: "Price linkage management",
    id: "5",
    icon: IconChain,
    children: [
      {
        name: "Purchase and Sales Linkage",
        id: "5-1",
        children: [
          {
            name: "submission details",
            id: "5-1-1",
            path: "/hdyBuyAndSellSystem",
          },
          {
            name: "Raw material price difference",
            id: "5-1-2",
            path: "/hdyPriceMargin",
          },
          {
            name: "BOM unit consumption",
            id: "5-1-3",
            path: "/hdyPricePlate",
          },
          {
            name: "Purchase and sales calculation details",
            id: "5-1-4",
            path: "/hdyPriceDetail",
          },
          {
            name: "Plate module calculation details",
            id: "5-1-5",
            path: "/hdyPricePlateDetail",
          },
        ],
      },
      {
        name: "Material Linkage",
        id: "5-2",
        children: [
          {
            name: "submission details",
            id: "5-2-1",
            path: "/hdyLinkageSubmit",
          },
          {
            name: "Linkage Rules",
            id: "5-2-2",
            path: "/hdyLinkageRule",
          },
          {
            name: "Protocol Management",
            id: "5-1-3",
            path: "/hdyProtocolSupervise",
          },
          {
            name: "BOM Management",
            id: "5-1-4",
            path: "/hdyBomSupervise",
          },
          {
            name: "Material Management",
            id: "5-1-5",
            path: "/hdyRawStockSupervise",
          },
          {
            name: "Four-way valve raw material base price",
            id: "5-1-6",
            path: "/hdyMatnrReferencePrice",
          },
          {
            name: "Four-way valve base price",
            id: "5-1-7",
            path: "/hdySapPrice",
          },
          {
            name: "Calculation Details",
            id: "5-1-7",
            path: "/hdyBomClassCalculationDetail",
          },
        ],
      },
      {
        name: "Packing box linkage",
        id: "5-3",
        children: [
          {
            name: "submission details",
            id: "5-3-1",
            path: "/hdyStandardCountBoxSubmit",
          },
          {
            name: "Calculation Details",
            id: "5-3-2",
            path: "/hdyStandardCountBoxCalculate",
          },
          {
            name: "Standard linkage rules",
            id: "5-3-3",
            path: "/hdyStandardLinkageRule",
          },
          {
            name: "Material Management",
            id: "5-3-4",
            path: "/hdyStandardRawMaterialManagement",
          },
          {
            name: "Standard Accounting BOM Management",
            id: "5-3-5",
            path: "/hdyStandardCountBom",
          },
          {
            name: "Standard accounting calculation details",
            id: "5-3-6",
            path: "/hdyStandardCountCalculateDetail",
          },
          {
            name: "Standard Accounting Management",
            id: "5-3-7",
            path: "/hdyStandardCountManagement",
          },
        ],
      },
      {
        name: "Raw material linkage (including processing fee)",
        id: "5-4",
        children: [
          {
            name: "submission details",
            id: "5-4-1",
            path: "/hdyFoilPresentation",
          },
          {
            name: "Protocol Management",
            id: "5-4-2",
            path: "/hdyFoilConsultativeManagement",
          },
          {
            name: "Linkage Rules",
            id: "5-4-3",
            path: "/hdyFoilLinkageRule",
          },
          {
            name: "Processing fee standard",
            id: "5-4-4",
            path: "/hdyFoilStandard",
          },
          {
            name: "Module specification",
            id: "5-4-5",
            path: "/hdyFoilMaterial",
          },
          {
            name: "Exchange rate information maintenance",
            id: "5-4-6",
            path: "/hdyFoilRate",
          },
          {
            name: "Maintenance of raw material prices",
            id: "5-4-7",
            path: "/hdyFoilMatnr1",
          },
          {
            name: "Calculation Details",
            id: "5-4-8",
            path: "/hdyFoilDetail",
          },
        ],
      },
      {
        name: "Lock Copper Management",
        id: "5-5",
        children: [
          {
            name: "submission details",
            id: "5-4-1",
            path: "/hdyBcSuotongSubmitDetail",
          },
          {
            name: "Processing fee standard",
            id: "5-4-2",
            path: "/hdyBcSuotongProcessFee",
          },
          {
            name: "BOM Management",
            id: "5-4-3",
            path: "/hdyBcSuotongBomManagement",
          },
          {
            name: "Exchange rate information maintenance",
            id: "5-4-4",
            path: "/hdyBcSuotongRate",
          },
          {
            name: "Lock Copper Price Relationship Table",
            id: "5-4-5",
            path: "/hdyBcSuotongPrice",
          },
          {
            name: "Calculation Details",
            id: "5-4-6",
            path: "/hdyBcSuotongCalDetail",
          },
        ],
      },
    ],
  },
  {
    name: "Price Accounting Management",
    id: "6",
    icon: IconCalculator,
    children: [
      {
        name: "Based on pricing standards",
        id: "6-1",
        children: [
          {
            name: "submission details",
            id: "6-1-1",
            path: "/hdyStandardCountBusinessScenario",
          },
          {
            name: "EBS standard number information maintenance",
            id: "6-1-2",
            path: "/hdyStandardCountEbsInfo",
          },
          {
            name: "PLM Information Entry",
            id: "6-1-3",
            path: "/hdyStandardCountPlmInfo",
          },
          {
            name: "Calculation Details",
            id: "6-1-4",
            path: "/hdyStandardCountCalculateInfo",
          },
        ],
      },
      {
        name: "Bulk steel plate price calculation",
        id: "6-2",
        children: [
          {
            name: "submission details",
            id: "6-2-1",
            path: "/hdySteelScene",
          },
          {
            name: "Size material BOM management",
            id: "6-2-2",
            path: "/hdySteelBom",
          },
          {
            name: "Annual data",
            id: "6-2-3",
            path: "/hdySteelYear",
          },
          {
            name: "Raw material price difference for cut-to-size materials",
            id: "6-2-4",
            path: "/hdySteelInterfaceFixedSize",
          },
          {
            name: "Color plate raw material price difference",
            id: "6-2-5",
            path: "/hdySteelColorBoard",
          },
          {
            name: "Calculation Details",
            id: "6-2-6",
            path: "/hdySteelDetail",
          },
        ],
      },
    ],
  },
  {
    name: "Daily Data Management",
    id: "7",
    icon: IconBar_chart,
    children: [
      {
        name: "Price business scenario",
        id: "7-1",
        path: "/hdyPriceBusinessScenario",
      },
      {
        name: "Other SAP business scenarios",
        id: "7-2",
        path: "/hdyOtherBusinessScenarios",
      },
      {
        name: "Mutual Transfer of Wisdom Parts",
        id: "7-3",
        path: "/hdyDailyDataCreativeComponentsSameMaterial",
      },
      {
        name: "Quota Business Scenario",
        id: "7-4",
        path: "/hdyQuotaBusinessScenario",
      },
      {
        name: "Business Type",
        id: "7-5",
        path: "/hdyDailyDataConfig",
      },
      {
        name: "Maintenance Configuration",
        id: "7-6",
        path: "/hdyMaintenanceConfiguration",
      },
    ],
  },
  {
    name: "Validity Period Management",
    id: "8",
    icon: IconClock,
    path: "/hdyBcEffectTimeEntrySystem",
  },
  {
    name: "Material Group Effective Management",
    id: "9",
    icon: IconBitbucket_square,
    path: "/hdyMaterialGroupTime",
  },
  {
    name: "Invalid Data Management",
    id: "10",
    icon: IconWindow_close,
    path: "/hdyBcInvalidDataBusinessScenarios",
  },
  {
    name: "Technical Transformation Management",
    id: "11",
    icon: IconCog,
    path: "/hdyTechnicalTransformationManagement",
  },
  {
    name: "Rebate Management",
    id: "12",
    icon: IconUndo,
    children: [
      {
        name: "Rebate Reconciliation Management",
        id: "12-1",
        path: "/hdyBcRebate",
      },
      {
        name: "Rebate Scenario Configuration",
        id: "12-2",
        path: "/hdyBcRebateScene",
      },
      {
        name: "Rebate agreement entry",
        id: "12-3",
        path: "/hdyBcRebateProtocol",
      },
      {
        name: "Rebate cash industry",
        id: "12-4",
        path: "/hdyCashDetailsFirst",
      },
      {
        name: "rebate single consumption re-record",
        id: "12-5",
        path: "/hdyBcRebateDanhao",
      },
      {
        name: "Rebate account management",
        id: "12-6",
        children: [
          {
            name: "Rebate entry management",
            id: "12-6-1",
            path: "/hdyInvoiceEntryFirst",
          },
          {
            name: "Rebate discount management",
            id: "12-6-2",
            path: "/hdyBcRebateDiscountFirst",
          },
        ],
      },
      {
        name: "Rebate status summary table",
        id: "12-7",
        path: "/hdyStateSummary",
      },
      {
        name: "Air pressure low price management",
        id: "12-8",
        path: "/hdyBcRebateKydj",
      },
    ],
  },
  {
    name: "New Rebate Management",
    id: "13",
    icon: IconUndo_alt,
    children: [
      {
        name: "Rebate Reconciliation Management",
        id: "13-1",
        path: "/hdyBcRebateNew",
      },
      {
        name: "Rebate agreement entry",
        id: "13-2",
        path: "/hdyBcRebateProtocolNew",
      },
      {
        name: "Rebate entry management",
        id: "13-3",
        path: "/hdyInvoiceEntryFirstNew",
      },
      {
        name: "Rebate status summary table",
        id: "13-3",
        path: "/hdyStateSummaryNew",
      },
    ],
  },
  {
    name: "OEM small and micro data management",
    id: "14",
    icon: IconShare_alt_square,
    path: "/hdyBusinessScenario",
  },
  {
    name: "Process Overview",
    id: "15",
    icon: IconSitemap,
    children: [
      {
        name: "A list of transfer processes",
        id: "15-1",
        path: "/unfinishList",
      },
      {
        name: "Complete process list",
        id: "15-2",
        path: "/finishList",
      },
      {
        name: "User Details",
        id: "15-3",
        path: "/user",
      },
    ],
  },
  {
    name: "General Report Management",
    id: "16",
    icon: IconFolder,
    children: [
      {
        name: "Cost Center Report",
        id: "16-1",
        path: "/hdyBcLifecyclePrice",
      },
      {
        name: "Unclosed-loop first-level table and second-level table",
        id: "16-2",
        path: "/noCloseOneTwoTable",
      },
    ],
  },
  {
    name: "Bottom report management",
    id: "17",
    icon: IconFolder_minus,
    children: [
      {
        name: "full life cycle",
        id: "17-1",
        path: "/hdybcFullLifeCircle",
      },
      {
        name: "Cost reduction dimension display",
        id: "17-2",
        path: "/hdyBcReducedDimensionDisplay",
      },
      {
        name: "Price changes abnormally",
        id: "17-3",
        path: "/hdyAbnormalPriceChange",
      },
      {
        name: "Price increase application statistics",
        id: "17-4",
        path: "/priceIncrease",
      },
      {
        name: "User Login Statistics",
        id: "17-5",
        path: "/hdyBcUserMonitor",
      },
      {
        name: "Raw material linkage calculation",
        id: "17-6",
        children: [
          {
            name: "submission details",
            id: "17-6-1",
            path: "/hdyRMSubmitDetail",
          },
          {
            name: "Calculation Details",
            id: "17-6-2",
            path: "/hdyRMCalculationDetail",
          },
          {
            name: "Material Management",
            id: "17-6-3",
            path: "/hdyRMPriceAdjustment",
          },
        ],
      },
      {
        name: "T + 13 Week Cost Estimate",
        id: "17-7",
        children: [
          {
            name: "Linkage Raw Material Market Forecast",
            id: "17-7-1",
            path: "/hdyLinkagePrice",
          },
          {
            name: "Buying and selling raw material price forecast",
            id: "17-7-2",
            path: "/hdyBcPurchaseAndSale",
          },
          {
            name: "Bulk purchase price forecast for direct supply",
            id: "17-7-3",
            path: "/hdyBcDirectSupply",
          },
          {
            name: "Module price adjustment forecast",
            id: "17-7-4",
            path: "/hdyModule",
          },
          {
            name: "Design Project Forecast",
            id: "17-7-5",
            path: "/hdyBcDesignEntry",
          },
          {
            name: "Module price forecast summary display",
            id: "17-7-6",
            path: "/hdyLinkageAllShow",
          },
        ],
      },
    ],
  },
  {
    name: "Second and third level material linkage management",
    id: "18",
    icon: IconLink,
    children: [
      {
        name: "Second and third-level material BOM table",
        id: "18-1",
        path: "/hdyMaterialBom",
      },
      {
        name: "Second and third level material price library",
        id: "18-1",
        path: "/hdyMaterialBomPrice",
      },
      {
        name: "EBS price into the system",
        id: "18-2",
        path: "/hdyEbsPrice",
      },
      {
        name: "Second and third level price adjustment",
        id: "18-3",
        path: "/hdyPriceAdjustment",
      },
      {
        name: "Secondary and third-level material difference",
        id: "18-4",
        path: "/hdyPriceShowdiff",
      },
      {
        name: "submission details",
        id: "18-5",
        path: "/hdySubmit",
      },
      {
        name: "Calculation Details",
        id: "18-6",
        path: "/MaterialLinkage_hdyBomClassCalculationDetail",
      },
    ],
  },
]

In the process, there is a problem that I have not figured out, that is, after the routing is enabled, the index should be used to jump, but an error will be reported when using item. I haven’t figured it out yet, and then I changed it to item.id to successfully jump. Quite strange. Because there are all numbers in the id, but the jump is indeed realized.