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

  • Post author:
  • Post category:vue




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>



版权声明:本文为qq_36687211原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。