【vue3 + element-plus】利用json数据进行动态路由渲染、动态多级菜单渲染

json文件

router.json

[
    {
    
     
        "path": "/" ,
        "redirect": "/index"
    },
      
    {
    
     
        "path": "/index", 
        "name":"index",
        "component": "layout/index.vue" ,
        "redirect": "/home",
        "children":[
            {
    
     
                "path": "/home", 
                "name":"home",
                "component": "views/home.vue",
                "meta":{
    
    
                    "title": "首页",
                    "icon": "House"
                }
            },
            {
    
     
                "path": "/apexchart", 
                "name":"apexchart",
                "component": "views/apexchart.vue",
                "meta":{
    
    
                    "title":"图表",
                    "icon":"DataAnalysis"
                }
            },
            {
    
    
                "path": "/widget",
                "name": "widget",
                "component": "views/widget/index.vue",
                "meta":{
    
    
                    "title": "小组件",
                    "icon": "Wallet"
                },
                "children":[
                    {
    
    
                        "path": "/tableRelated",
                        "name": "tableRelated",
                        "component": "views/widget/tableRelated.vue",
                        "meta":{
    
    
                            "title": "表格相关",
                            "icon": "Memo"
                        }  
                    }
                ]
                    
                    
                
            },
            {
    
    
                "path": "/cssRelated",
                "name": "cssRelated",
                "component": "views/cssRelated/index.vue",
                "meta":{
    
    
                    "title": "CSS相关组件",
                    "icon": "Suitcase"
                }
            }
        ]
    },
    {
    
    
        "path":"/error",
        "name": "error",
        "component": "views/error.vue",
        "meta": {
    
    
            "title": "404页面"
        }
    },
    {
    
    
        "path": "/:catchAll(.*)",
        "redirect": "/error"
      }
      
]

路由

src\router\index.js

import {
    
     createRouter, createWebHistory } from 'vue-router'
import datas from "@/assets/json/router.json"

// 将 json 数据转换为一个普通数组
const menuData = JSON.parse(JSON.stringify(datas))

// 处理动态引入组件函数
const getComponent = (data) =>{
    
    
  data.map( item => {
    
    
    const url =  item.component
    item.component = ()=> import (`@/${
      
      url}`)

    // 处理多级路由
    if(item.children && item.children.length){
    
    
      getComponent(item.children)
    }
  })

  return data
}

// 获取处理后的理由数据
const routerData = getComponent(menuData)  
console.log('routerData',routerData);

// 配置路由

let router = createRouter({
    
    
    // 3.0 需要配置对应的路由模式
    history: createWebHistory(),
    // 配置路由
    routes: routerData
  })

  router.beforeEach(async (to) =>{
    
    
    console.log('111111',to);
  })
  // 暴露路由对象
  export default router

多级菜单组件

  • Menu.vue
<template>
    <div  style="width: 100%;height:100%;">
        <el-menu :default-active="paths" router  style="height:100%;">
            <MenuTree :menuData="menuDatas"></MenuTree>
        </el-menu>
    </div>
</template>

<script >
import {
      
       useRoute } from "vue-router"
import datas from "@/assets/json/router.json"
import MenuTree from "./MenuTree.vue"

export default {
      
      
    name: 'Menu',
    components: {
      
      
        MenuTree
    },
    data() {
      
      
        return{
      
      
            menuDatas:"",
            paths:useRoute().path
        }
    },
    created() {
      
      
        let data = JSON.parse(JSON.stringify(datas)) 
            data = data.filter((item)=>{
      
      
                return item.name == "index"
            })
            this.menuDatas = data[0].children
            // console.log('MenuDatas1',this.menuDatas);
    },
    methods: {
      
      
    }
}
</script>

<style scoped lang='scss'>

</style>
  • MenuTree.vue
<template>
    <div >
        <template v-for="(item, index) in menuData" :key="index">
            <!-- 无子目录 -->
            <el-menu-item v-if="!item.children" :index="item.path">
                <el-icon v-if="item.meta.icon">
                    <!-- <House /> -->
                    <component :is="item.meta.icon"></component>
                </el-icon>
                <span>{
   
   { item.meta.title }}</span>
            </el-menu-item>

            <!-- 有子目录 -->
            <el-sub-menu :index="item.path" v-if="item.children">
                <template #title>
                    <el-icon v-if="item.meta.icon">
                        <component :is="item.meta.icon"></component>
                    </el-icon>
                    <span>{
   
   { item.meta.title }}</span>
                </template>
                <MenuTree :menuData="item.children"></MenuTree>
            </el-sub-menu>
        </template>
    </div>
</template>

<script >
import MenuTree from "./MenuTree.vue"

export default {
      
      
    name: 'MenuTree',
    components: {
      
      
        MenuTree
    },
    props:["menuData"],
    data() {
      
      
        return{
      
      
            
        }
    },
    created() {
      
      
    },
    methods: {
      
      
        
    }
}
</script>

<style scoped lang='scss'>

</style>

猜你喜欢

转载自blog.csdn.net/qq_36687211/article/details/128632719