vue + ElementUI 点击页面内按钮跳转,导航栏选中问题

本文解决了Vue结合ElementUI项目中,使用按钮跳转页面时导航栏无法正确高亮显示的问题。通过计算属性动态设置激活菜单项,确保无论通过何种方式跳转,导航栏都能准确显示当前页面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

vue + ElementUI 点击导航栏跳转页面是可以正常跳转高亮的,但通过页面内点击按钮跳转页面就会导致侧边栏不知道该选中那个了,下面说下解决方法

 <el-menu class="sidebar-el-menu"  :default-active="onRoutes" >
            </el-menu>
     computed:{
            onRoutes(){
                // this.$route.path
                // debugger
                if(this.$route.path.replace('/','')=='ProductEdit'){
                   return 'Product'; 
                }
                else if(this.$route.path.replace('/','')=='OrderDetail'){
                    return 'Order'
                }
                else{
                    return this.$route.path.replace('/','');
                }

            },
            }

花了一个多小时终于搞定

<think>我们使用Vue2和ElementUI来实现一个侧边导航栏点击切换右侧页面的功能。主要步骤:1.创建Vue2项目并安装ElementUI2.配置路由(使用vue-router)3.封装侧边导航栏组件(使用el-menu)4.在App.vue中布局,左侧为导航栏,右侧为路由视图(router-view)5.实现点击导航菜单切换路由,右侧显示对应页面注意:这里我们使用vue-router来实现页面切换。具体代码实现如下:第一步:创建项目(如果已有项目可跳过)```bashvuecreatemy-projectcdmy-projectvueaddrouternpminstallelement-ui```第二步:在main.js中引入ElementUI```javascriptimportVuefrom'vue'importAppfrom'./App.vue'importrouterfrom'./router'importElementUIfrom'element-ui';import'element-ui/lib/theme-chalk/index.css';Vue.use(ElementUI);newVue({router,render:h=>h(App)}).$mount('#app')```第三步:配置路由(router/index.js)```javascriptimportVuefrom'vue'importRouterfrom'vue-router'Vue.use(Router)exportdefaultnewRouter({routes:[{path:'/',name:'Home',component:()=>import('@/views/Home.vue')},{path:'/about',name:'About',component:()=>import('@/views/About.vue')},{path:'/contact',name:'Contact',component:()=>import('@/views/Contact.vue')}]})```第四步:创建页面组件(在views目录下创建Home.vue,About.vue,Contact.vue)例如:Home.vue```vue<template><div><h1>首页</h1></div></template>```第五步:封装侧边导航栏组件(components/Sidebar.vue)注意:这里我们使用el-menu,并且设置router属性为true,这样就会以index作为path进行路由跳转。```vue<template><el-menudefault-active="/"class="el-menu-vertical-demo"background-color="#545c64"text-color="#fff"active-text-color="#ffd04b"router><el-menu-itemindex="/"><iclass="el-icon-menu"></i><spanslot="title">首页</span></el-menu-item><el-submenuindex="1"><templateslot="title"><iclass="el-icon-setting"></i><span>设置</span></template><el-menu-itemindex="/about">关于</el-menu-item><el-menu-itemindex="/contact">联系方式</el-menu-item></el-submenu></el-menu></template><script>exportdefault{name:'Sidebar'}</script><stylescoped>.el-menu-vertical-demo{height:100vh;}</style>```第六步:在App.vue中使用布局```vue<template><el-containerstyle="height:100vh;"><el-asidewidth="200px"><sidebar></sidebar></el-aside><el-container><el-main><router-view></router-view></el-main></el-container></el-container></template><script>importSidebarfrom'@/components/Sidebar.vue'exportdefault{components:{Sidebar}}</script><style>body{margin:0;}</style>```这样,我们就完成了侧边导航栏的封装和页面切换功能。说明:1.在Sidebar组件中,el-menu的router属性设置为true,这样每个菜单项的index值就会作为路由路径进行跳转。2.我们使用el-container布局,左侧是导航栏,右侧是主内容区,主内容区使用router-view来显示当前路由对应的组件。效果:点击左侧导航菜单,右侧会显示对应的页面。扩展:如果需要动态生成菜单,可以从后台获取数据,然后使用v-for循环生成菜单项。例如:在Sidebar组件中,我们可以这样写:```vue<template><el-menu:default-active="$route.path"class="el-menu-vertical-demo"background-color="#545c64"text-color="#fff"active-text-color="#ffd04b"router><templatev-for="iteminmenuList"><el-menu-itemv-if="!item.children":index="item.path":key="item.path"><i:class="item.icon"></i><spanslot="title">{{item.title}}</span></el-menu-item><el-submenuv-else:index="item.path":key="item.path"><templateslot="title"><i:class="item.icon"></i><span>{{item.title}}</span></template><el-menu-itemv-for="subIteminitem.children":index="subItem.path":key="subItem.path">{{subItem.title}}</el-menu-item></el-submenu></template></el-menu></template><script>exportdefault{data(){return{menuList:[{path:'/',title:'首页',icon:'el-icon-menu'},{path:'/setting',title:'设置',icon:'el-icon-setting',children:[{path:'/about',title:'关于'},{path:'/contact',title:'联系方式'}]}]}}}</script>```注意:动态生成菜单时,需要确保每个菜单项的index(即path)与路由配置中的path一致。相关问题:1.如何实现导航菜单的折叠和展开?答:可以使用ElementUI的NavMenu的collapse属性,并配合一个折叠按钮来控制。具体实现可参考引用[1]中的父子组件通信方式。2.如何根据用户权限动态生成菜单?答:在获取菜单数据时,根据用户角色过滤菜单项,然后再渲染。3.如何让侧边导航栏支持多级嵌套?答:使用递归组件,或者像上面那样使用两层v-for(但层级固定),递归组件可参考引用[3]。4.如何自定义菜单项的样式?答:可以通过覆盖ElementUI的默认样式,或者使用引用[2]中的自定义样式方法。5.如何实现面包屑导航?答:可以在顶部添加一个面包屑组件,根据当前路由生成面包屑路径。希望这个示例能帮助到你。</think>下面是一个在 Vue 2 中使用 ElementUI 封装侧边导航栏并实现页面切换的完整示例: ### 完整实现方案 #### 1. 项目准备 ```bash # 安装依赖 npm install vue@2 element-ui vue-router ``` #### 2. 文件结构 ``` src/ ├── router/ │ └── index.js # 路由配置 ├── components/ │ └── Sidebar.vue # 侧边导航组件 ├── views/ │ ├── Home.vue # 页面组件 │ ├── About.vue │ └── Contact.vue ├── App.vue # 主组件 └── main.js # 入口文件 ``` #### 3. 路由配置 (`src/router/index.js`) ```javascript import Vue from 'vue' import Router from 'vue-router' import Home from '@/views/Home.vue' import About from '@/views/About.vue' import Contact from '@/views/Contact.vue' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'Home', component: Home }, { path: '/about', name: 'About', component: About }, { path: '/contact', name: 'Contact', component: Contact } ] }) ``` #### 4. 侧边导航组件 (`src/components/Sidebar.vue`) ```vue <template> <el-menu :default-active="activeMenu" class="sidebar-menu" background-color="#304156" text-color="#bfcbd9" active-text-color="#409EFF" router @select="handleSelect" > <el-menu-item index="/"> <i class="el-icon-menu"></i> <span>首页</span> </el-menu-item> <el-submenu index="sub1"> <template slot="title"> <i class="el-icon-setting"></i> <span>系统设置</span> </template> <el-menu-item index="/about"> <i class="el-icon-info"></i> <span>关于我们</span> </el-menu-item> <el-menu-item index="/contact"> <i class="el-icon-phone"></i> <span>联系方式</span> </el-menu-item> </el-submenu> </el-menu> </template> <script> export default { name: 'Sidebar', data() { return { activeMenu: '/' } }, watch: { // 监听路由变化更新激活菜单 '$route.path': { immediate: true, handler(newPath) { this.activeMenu = newPath } } }, methods: { handleSelect(index) { console.log('导航到:', index) // 触发自定义事件通知父组件 this.$emit('menu-select', index) } } } </script> <style scoped> .sidebar-menu { height: 100%; border-right: none; } .el-menu-item.is-active { background-color: #1f2d3d !important; } </style> ``` #### 5. 主应用布局 (`src/App.vue`) ```vue <template> <el-container class="layout-container"> <!-- 侧边导航 --> <el-aside width="200px"> <sidebar @menu-select="handleMenuSelect" /> </el-aside> <!-- 主内容区 --> <el-container> <el-header height="50px" style="border-bottom: 1px solid #e6e6e6;"> <div class="header-content"> <el-breadcrumb separator="/"> <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item> <el-breadcrumb-item v-for="(item, index) in breadcrumbs" :key="index"> {{ item }} </el-breadcrumb-item> </el-breadcrumb> </div> </el-header> <el-main> <!-- 页面显示区域 --> <router-view></router-view> </el-main> </el-container> </el-container> </template> <script> import Sidebar from '@/components/Sidebar.vue' export default { name: 'App', components: { Sidebar }, data() { return { breadcrumbs: [] } }, watch: { // 根据路由生成面包屑 '$route': { immediate: true, handler(route) { this.breadcrumbs = route.matched .filter(record => record.name && record.name !== 'Home') .map(record => record.name) } } }, methods: { handleMenuSelect(path) { console.log('菜单选中:', path) } } } </script> <style> .layout-container { height: 100vh; } .el-header { background: #fff; display: flex; align-items: center; } .header-content { width: 100%; } </style> ``` #### 6. 页面组件示例 (`src/views/About.vue`) ```vue <template> <div class="page-content"> <h1>关于我们</h1> <p>这里是关于页面的内容...</p> </div> </template> <script> export default { name: 'About' } </script> <style scoped> .page-content { padding: 20px; } </style> ``` #### 7. 入口文件 (`src/main.js`) ```javascript import Vue from 'vue' import App from './App.vue' import router from './router' import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' Vue.use(ElementUI) new Vue({ router, render: h => h(App) }).$mount('#app') ``` ### 关键功能说明 1. **路由集成导航**: - 使用 `<el-menu router>` 实现路由跳转 - `default-active` 绑定当前路由路径实现菜单高亮 - 通过 `$route.path` 监听路由变化 2. **面包屑导航**: - 使用 `$route.matched` 获取当前路由匹配信息 - 过滤生成面包屑路径显示在顶部 3. **菜单样式定制**: - 使用 ElementUI 的深色主题配色方案 - 自定义激活菜单项的样式 - 添加菜单项图标增强视觉效果[^2] 4. **组件通信**: - 使用 `$emit` 触发自定义事件通知父组件菜单选择 - 父组件通过 `@menu-select` 监听菜单选择事件 ### 扩展功能实现 #### 1. 菜单折叠功能 (参考引用[1]) ```vue <!-- Sidebar.vue --> <template> <div> <el-button @click="isCollapse = !isCollapse">折叠/展开</el-button> <el-menu :collapse="isCollapse" <!-- 其他属性 --> > <!-- 菜单内容 --> </el-menu> </div> </template> <script> export default { data() { return { isCollapse: false } } } </script> ``` #### 2. 动态菜单数据 (参考引用[3]) ```vue <!-- Sidebar.vue --> <template> <el-menu> <template v-for="item in menuData"> <el-submenu v-if="item.children" :key="item.index" :index="item.index"> <template slot="title"> <i :class="item.icon"></i> <span>{{ item.title }}</span> </template> <el-menu-item v-for="child in item.children" :key="child.index" :index="child.path" > {{ child.title }} </el-menu-item> </el-submenu> <el-menu-item v-else :key="item.index" :index="item.path"> <i :class="item.icon"></i> <span>{{ item.title }}</span> </el-menu-item> </template> </el-menu> </template> <script> export default { data() { return { menuData: [ { index: '1', title: '首页', icon: 'el-icon-menu', path: '/' }, { index: '2', title: '系统设置', icon: 'el-icon-setting', children: [ { index: '2-1', title: '关于我们', path: '/about' }, { index: '2-2', title: '联系方式', path: '/contact' } ] } ] } } } </script> ``` #### 3. 自定义弹出菜单样式 (参考引用[2]) ```css /* 在Sidebar.vue中添加 */ .el-menu--popup { background: #1A2B53 !important; padding: 0 !important; } .el-menu--popup .el-menu-item { color: #fff !important; font-weight: bold; } .el-menu--popup .el-menu-item:hover { background: #1a4177 !important; } .el-menu--popup .el-menu-item.is-active { background: #1a4177 !important; } ``` ### 常见问题解决方案 1. **菜单高亮不更新问题**: ```javascript // 在Sidebar.vue中添加 watch: { '$route.path': { immediate: true, handler(newPath) { this.activeMenu = newPath; // 解决子菜单激活状态问题 this.$nextTick(() => { this.$refs.menu && this.$refs.menu.updateOpened(); }); } } } ``` 2. **多级菜单路由配置**: ```javascript // router/index.js { path: '/system', component: SystemLayout, children: [ { path: 'about', component: About }, { path: 'contact', component: Contact } ] } ``` 3. **权限控制菜单显示**: ```javascript computed: { filteredMenu() { return this.menuData.filter(item => { // 根据用户权限过滤菜单 return this.$store.getters.hasPermission(item.requiredPermission); }); } } ``` 4. **菜单折叠状态保存**: ```javascript // 使用localStorage保存折叠状态 mounted() { const savedState = localStorage.getItem('menuCollapsed'); if (savedState) this.isCollapse = JSON.parse(savedState); }, watch: { isCollapse(newVal) { localStorage.setItem('menuCollapsed', JSON.stringify(newVal)); } } ``` ### 相关问题 1. 如何实现动态路由和菜单权限控制? 答:通过路由守卫结合用户角色动态生成可访问路由[^1] 2. ElementUI 的导航菜单如何支持无限层级嵌套? 答:使用递归组件渲染多级菜单[^3] 3. 如何实现路由切换时的页面缓存? 答:使用 `<keep-alive>` 结合路由元信息缓存特定页面 4. 面包屑导航如何根据路由参数动态显示? 答:在路由元信息中定义面包屑生成函数 5. 如何优化侧边栏在移动端的显示效果? 答:添加响应式断点控制侧边栏折叠状态[^1] 6. 如何自定义菜单弹出框的样式? 答:通过深度选择器覆盖 ElementUI 默认样式[^2] [^1]: Vue+ElementUI 实现导航菜单折叠功能 [^2]: ElementUI 导航菜单自定义样式实现 [^3]: Vue 递归组件实现多级菜单导航
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值