vue版本根据当前路由匹配到根父节点并且激活

Posted pengfei25

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue版本根据当前路由匹配到根父节点并且激活相关的知识,希望对你有一定的参考价值。

页面布局

我的项目是有两种布局方式的, 一种是左侧布局,还有一种是顶部+左侧的布局,在这里主要讲顶部+左侧布局  因为左侧的相对简单,会自行匹配

业务场景

  当页面刷新的时候,要回到原来的页面,并且要激活正确的一级和二级菜单

首先  在data中创建数据

            data() {
                return {
                    menus: [],//菜单数据是id pid 加上children格式的
                    parentNodes: [] //最终调用函数返回的结果集 
                }
            },

 

 获取当前页面路由的id和pid

            let path = this.$route.path
            let id = this.$route.meta.id
            let pid = this.$route.meta.pid

 

最后返回的时候 当前路由的根节点的节点数据

截图

技术图片

 

 

 

 

 

测试代码:  因为是 cdn引入的没有看出效果

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>智能社——http://www.zhinengshe.com</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <style>

    </style>
    <!--<script src="vue.js"></script>-->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="box">
        {{msg}}
    </div>
    <script>
        new Vue({
            el:#box,
            data() {
                return {
                    msg:123,
                    menus: [],
                    active: 0,
                    parentNodes: []
                }
            },
            created:function(){
                this.menus= [{"id":"3","name":"平台管理","url":"/platformManage","type":"0","grade":"1","parent":"0","permission":"gfd","modeType":"1","entry":null,"params":null,"treeType":null,"sort":1,"children":[{"id":"4","name":"组态设计","url":"/pageManage","type":"0","grade":"2","parent":"3","permission":"gfd","modeType":"1","entry":"modules/configuration/views/entry/PageManage","params":null,"treeType":null,"sort":20,"children":[]},{"id":"25","name":"标志牌定义","url":"/tokenDefine","type":"0","grade":"2","parent":"3","permission":"","modeType":"1","entry":"modules/control/tokenDefine/TokenDefine","params":"","treeType":"","sort":25,"children":[]}]},{"id":"1","name":"告警管理","url":"/alarmManage","type":"0","grade":"1","parent":"0","permission":"alarm","modeType":"1","entry":null,"params":null,"treeType":null,"sort":2,"children":[{"id":"2","name":"告警事件","url":"/alarmEvents","type":"0","grade":"2","parent":"1","permission":"fd","modeType":"1","entry":"modules/alarm/alarmEvents/AlarmEvents","params":null,"treeType":null,"sort":14,"children":[]},{"id":"24","name":"告警屏蔽","url":"/alarmShield","type":"0","grade":"2","parent":"1","permission":"fd","modeType":"1","entry":"modules/alarm/alarmConfig/alarmShield/AlarmShield","params":null,"treeType":null,"sort":19,"children":[]},{"id":"28","name":"知识库","url":"/alarmKnowledge","type":"0","grade":"2","parent":"1","permission":null,"modeType":"1","entry":"modules/alarm/alarmKnowledge/Knowledge","params":null,"treeType":null,"sort":22,"children":[]},{"id":"29","name":"告警级别","url":"/alarmLevel","type":"0","grade":"2","parent":"1","permission":"fd","modeType":"1","entry":"modules/alarm/alarmConfig/alarmLevel/AlarmLevel","params":null,"treeType":null,"sort":25,"children":[]}]},{"id":"19","name":"电力监控","url":"/pscadaIndex","type":"0","grade":"1","parent":"0","permission":null,"modeType":"1","entry":"modules/configuration/views/configView/index","params":"filename=数据中心&category=5","treeType":null,"sort":3,"children":[]},{"id":"17","name":"实时监控","url":"/first","type":"0","grade":"1","parent":"0","permission":null,"modeType":"1","entry":"","params":"","treeType":"","sort":4,"children":[{"id":"18","name":"动环监控","url":"/index","type":"0","grade":"2","parent":"17","permission":null,"modeType":"1","entry":"modules/configuration/views/configView/index","params":"filename=动环首页&category=5","treeType":"true","sort":13,"children":[]}]},{"id":"7","name":"服务管理","url":"/serviceManage","type":"0","grade":"1","parent":"0","permission":"aaaa","modeType":"1","entry":"","params":null,"treeType":null,"sort":5,"children":[{"id":"22","name":"服务实时信息","url":"/service","type":"0","grade":"2","parent":"7","permission":null,"modeType":"1","entry":"modules/servicemanagement/service/Service","params":null,"treeType":null,"sort":17,"children":[]},{"id":"23","name":"容器实时信息","url":"/container","type":"0","grade":"2","parent":"7","permission":null,"modeType":"1","entry":"modules/servicemanagement/container/Container","params":null,"treeType":null,"sort":18,"children":[]}]},{"id":"8","name":"系统管理","url":"/sysManage","type":"0","grade":"1","parent":"0","permission":"d","modeType":"1","entry":"","params":null,"treeType":null,"sort":6,"children":[{"id":"11","name":"资源管理","url":"/resouceManage","type":"0","grade":"2","parent":"8","permission":"bb","modeType":"1","entry":"modules/user/sourceList/SourceList","params":null,"treeType":null,"sort":9,"children":[]},{"id":"26","name":"用户管理","url":"/userManage","type":"0","grade":"2","parent":"8","permission":null,"modeType":"1","entry":"modules/user/userManage/UserManage","params":null,"treeType":null,"sort":21,"children":[]},{"id":"30","name":"登录首页配置","url":"/logAndIndexConfig","type":"0","grade":"2","parent":"8","permission":null,"modeType":"1","entry":"modules/sysconfs/conf/LoginIndexConfig","params":null,"treeType":null,"sort":23,"children":[]}]},{"id":"15","name":"日志管理","url":"/logMangage","type":"0","grade":"1","parent":"0","permission":null,"modeType":"1","entry":null,"params":null,"treeType":null,"sort":7,"children":[{"id":"16","name":"用户操作日志","url":"/userLog","type":"0","grade":"2","parent":"15","permission":null,"modeType":"1","entry":"modules/log/userLog/UserLog","params":null,"treeType":null,"sort":12,"children":[]},{"id":"20","name":"系统运行日志","url":"/sysLog","type":"0","grade":"2","parent":"15","permission":null,"modeType":"1","entry":"modules/log/sysLog/SysLog","params":null,"treeType":null,"sort":15,"children":[]},{"id":"21","name":"告警日志","url":"/alaramLog","type":"0","grade":"2","parent":"15","permission":null,"modeType":"1","entry":"modules/log/alarmLog/AlarmLog","params":null,"treeType":null,"sort":16,"children":[]}]}]
            },
            mounted(){
                //let id = this.$route.meta.id
                //let pid = this.$route.meta.pid
                //console.log(id, pid)
                let id = 1 ,pid = 2
                console.log(this.getParentsByAddressId({ id, pid, request: true }))
            },
              updated(){
                console.log(this.parentNodes)
            },
            methods:{
        //查找所有祖先节点
        findAllParent(node, tree, parentNodes = [], index = 0) {
            if (!node || node.pid === 0) {
                return
            }
            this.findParent(node, parentNodes, tree)
            let parentNode = parentNodes[index]
            this.findAllParent(parentNode, tree, parentNodes, ++index)
            return parentNodes
        },

        //查找父节点
        findParent(node, parentNodes, tree) {
            for (let i = 0; i < tree.length; i++) {
                let item = tree[i]
                if (item.id === node.pid) {
                    parentNodes.push(item)
                    return
                }
                if (item.children && item.children.length > 0) {
                    this.findParent(node, parentNodes, item.children)
                }
            }
        },

        //根据addressId查找对应的父节点及祖先节点
        getParentsByAddressId(addressInfos){
            //console.log(addressInfos)
            if(addressInfos.request){
                this.parentNodes = this.findAllParent(addressInfos, this.menus).reverse()
            }else{
                if(this.parentNodes[this.parentNodes.length-1].children.length>0){
                    this.parentNodes.push(addressInfos)
                }else{
                    this.parentNodes.splice(this.parentNodes.length-1,1,addressInfos) 
                }
            }
            //console.log(this.parentNodes)
        },
            }
        });
    </script>
</body>
</html>

实际代码:

技术图片
<template>
    <el-container :data-theme=‘base_theme‘>
        <el-header>
            <div class="logo">
                <!-- <span><img class="sys_logo" :src="!!logData.logopath?logData.logopath:Images.logopath" /></span> -->
                <span><img class="sys_logo" :src="logSrc" /></span>
                <span class="sys_name">{{sysName}}</span>
            </div>

            <!-- <span class="lang" @click="switchLang">语言</span>
                <span class="theme" @click="switchTheme">切换主题</span> -->
            <div>
                <span class="el-icon-switch-button quit" @click="quit" title="退出"></span>
                <div id="h-navbar">
                    <ul class="navbar">
                        <li class="" v-for="(item, index) in menus" :key="item.id" :class="{active:active==index?true:false}" @click="switchTab(index)">
                            <i class="em">|</i>
                            <a href="javascript:;">{{item.name}}</span>
                            </a>
                        </li>
                        <!-- <li><i class="em">|</i><a href="javascript:;">能源统计与分析</a></li>-->
                    </ul>
                </div>
                
            </div>
            <!-- 功能按钮 -->
            <!-- <div id="h-icon">
                    <i :class="item.icon" :title="item.text" v-for="(item,index) in logData.oper" :key="item.text" v-if="item.type==‘icon‘"></i>
                    <i :class="item.icon" :title="item.text" v-else>{{item.text}}</i>
                </div> -->
        </el-header>
        <el-container>
            <el-aside width="200px">
                <left-bar :menuData="menuData" />
            </el-aside>
            <el-container>
                <el-main>
                    <!-- 路由 -->
                    <self-bread :options="breadOptions" v-if="$route.meta.treeType!=null"/>
                    <section class="app-main">
                        <transition name="fade" mode="out-in">
                            <router-view ref="routerview" />
                        </transition>
                    </section>
                </el-main>
                <!-- <el-footer>Footer</el-footer> -->
            </el-container>
        </el-container>
    </el-container>
</template>
<script>
import Menus from @modules/baselayout/assets/json/menus.json
import SelfContrls from @frameworks/common
import LeftBar from ./views/LeftBar
import options from ./assets/js/configIndex
import lockr from lockr
import Api from @frameworks/conf/api
export default {
    mixins: [options],
    name: layout,
    components: {
        LeftBar
    },
    data() {
        return {
            menus: [],
            menuData: [],//传给leftbar的数据
            active: 0,
            parentNodes:[]
        }
    },
    methods: {
        //查找所有祖先节点
        findAllParent(node, tree, parentNodes = [], index = 0) {
            if (!node || node.pid === 0) {
                return
            }
            this.findParent(node, parentNodes, tree)
            let parentNode = parentNodes[index]
            this.findAllParent(parentNode, tree, parentNodes, ++index)
            return parentNodes
        },

        //查找父节点
        findParent(node, parentNodes, tree) {
            for (let i = 0; i < tree.length; i++) {
                let item = tree[i]
                if (item.id === node.pid) {
                    parentNodes.push(item)
                    return
                }
                if (item.children && item.children.length > 0) {
                    this.findParent(node, parentNodes, item.children)
                }
            }
        },

        //根据addressId查找对应的父节点及祖先节点
        getParentsByAddressId(addressInfos){
            //console.log(addressInfos)
            if(addressInfos.request){
                this.parentNodes = this.findAllParent(addressInfos, this.menus).reverse()
            }else{
                if(this.parentNodes[this.parentNodes.length-1].children.length>0){
                    this.parentNodes.push(addressInfos)
                }else{
                    this.parentNodes.splice(this.parentNodes.length-1,1,addressInfos) 
                }
            }
            //console.log(this.parentNodes)
        },
        init() {
            let menuData = lockr.get(menuData)
            let _menuData = menuData.filter((a)=>a.type == 0)
            this.menus = this.$_c.listToTree(_menuData, { idKey: id, parentKey: parent })
            //根据缓存的浏览器一级菜单的id设置初始化选中菜单 设置this.active
            // this.active = lockr.get(‘selectMenuId‘)
            // if (lockr.get(‘selectMenuId‘) != undefined && lockr.get(‘selectMenuId‘) != null) {
            //     this.switchTab(lockr.get(‘selectMenuId‘))
            // }
            //根据当前页面的路由选中一级二级菜单
            this.initSelectMenu()
        },
        initSelectMenu(){
            //获取当前页面的路由
            let path = this.$route.path
            console.log(path)
            console.log(JSON.stringify(this.menus))
            //匹配到一级菜单
            
            let id = this.$route.meta.id
            let pid = this.$route.meta.pid
            console.log(id,pid)
            this.getParentsByAddressId({ id, pid, request: true })
            
        },
        switchTab(index) {
            this.active = index
            this.menuData = this.menus[index].children
            //设置默认选中菜单下面的最后一个子节点
            let el = this.menus[index].children[0]
            while (el && el.children.length>0) {
                el = el.children[0]
            }
            console.log(el)
            if(!el){
                if (this.menus[index].entry != "" && this.menus[index].entry != null && this.menus[index].entry != undefined) {
                    el = this.menus[index]
                }
            }
            console.log(el.url)
            this.$router.push(el.url)
            lockr.set(selectMenuId, index)
            //通过id获取到菜单下面的按钮
            this.$ajax.get(Api.getNodesById+"/"+el.id).then((res) => {
                if (res.code === 200) {
                    let item = res.data
                    let permissionArr = []
                    if (item && item.length > 0) {
                        for (let i = 0; i < item.length; i++) {
                            permissionArr.push(item[i].url)
                        }
                    }
                    this.$store.dispatch(setPermission, permissionArr)
                } else {
                    this.$message.error(res.message)
                }
            })
        }
    },
    mounted() {
        this.init()
    },
    updated(){
        console.log(this.logData)
        console.log(this.parentNodes)
        console.log(this.parentNodes)
    }
};
</script>
<style lang="scss">
@import ‘../../frameworks/assets/css/theme.scss‘;
.logo {
    display: inline-block;
    height: 60px;
    line-height: 60px;
    &>span {
        float: left
    }
}

.logo,
#h-icon {
    display: inline-block;
    &>i {
        font-style: normal
    }
}

#h-icon {
    height: 60px;
    vertical-align: top
}

#h-navbar {
    //float: right; //display: inline-block;
    font-size: 0;
    height: 100%; // width: 800px;
    overflow: hidden;
    margin-right: 100px;
    .navbar {
        height: 100%; // width: 4000px;
        li {
            list-style: none;
            position: relative;
            display: inline-block;
            height: 100%;
            &>i {
                font-size: 14px;
                color: #59a5e4;
                font-weight: 700;
                font-style: normal;
                margin-right: 8px;
                cursor: default;
            }
            &>a {
                font-size: 16px;
                color: white;
                font-weight: 500
            }
        }
        li.active {
            &>a {
                color: #FFBD20
            }
        }
    }
}


.el-container {
    width: 100%;
    height: 100%;
}

.el-header {
    @include el-header-background();
    display: flex;
    justify-content: space-between;
}

.el-header,
.el-footer {
    color: $color_white;
    text-align: left;
    text-indent: 10px;
    line-height: 60px;
    & span.sys_name {
        font-size: 24px;
        margin-left: 5px;
        float: left;
    }
    & span.quit {
        //float: right;
        margin-right: 20px;
        font-size: 24px;
        margin-top: 18px;
    }
}

.el-aside {
    border: 1px solid #d2d2d2;
    color: #464C5B;
    text-align: center;
    line-height: $leftbar_width;
    height: calc(100vh - 60px);
    overflow: hidden!important; // box-shadow: 1px 0 6px #888888;
    z-index: 0;
}

.el-scrollbar {
    height: 100%
}

.el-main {
    background-color: $main_bg_color;
    color: #333;
    text-align: center;
    height: 100%;
    padding: 0!important;
}

.app-main {
    height: 100%;
}

body>.el-container {
    margin-bottom: 40px;
}

.el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {
    line-height: 260px;
}

.el-container:nth-child(7) .el-aside {
    line-height: 320px;
}

.lang {
    @include base-background();
}
</style>
View Code

以上是关于vue版本根据当前路由匹配到根父节点并且激活的主要内容,如果未能解决你的问题,请参考以下文章

vue 路由对象(常用的)

vue知识点-$route和$router

vue路由的active-class和exact-active-class区别

VUE路由原理

vue,react两种路由的简单原理

JS根据子节点递归获取所有父节点的集合