- router.js 中的代码
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
import Layout from '@/layout'
export const routes = [
{
path: '/login',
component: () => import('@/views/login'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/404'),
hidden: true
},
{
path: '/403',
component: () => import('@/views/403'),
hidden: true
},
{
path: '/',
component: Layout,
redirect: '/home',
children: [
{
path: 'home',
component(resolve) {
require(['@/views/home/index'], resolve)
},
name: 'Home',
meta: { title: '首页', icon: 'home', code: '' }
}
]
},
{
path: '/project',
component: Layout,
meta: {
title: '项目管理',
icon: 'project',
code: ''
},
children: [
{
path: 'project',
component(resolve) {
require(['@/views/project/index'], resolve)
},
name: 'Project',
meta: {
title: '项目',
code: ''
}
},
{
path: 'authorization',
component(resolve) {
require(['@/views/project/components/authorizationDialog'], resolve)
},
name: 'Authorization',
meta: {
title: '项目',
code: 'project-list-page'
},
hidden: true
}
]
}
]
const createRouter = () =>
new VueRouter({
// mode: 'history', // require service support
scrollBehavior: (to, from, savedPosition) => {
if (savedPosition) {
return savedPosition
} else {
return { x: 0, y: 0 }
}
},
routes
})
const router = createRouter()
router.selfaddRoutes = function (params) {
router.matcher = new VueRouter().matcher
router.addRoutes(params)
}
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
export default router
- 创建 SubMenu.vue(菜单组件的封装)
<template>
<div>
<template v-for="menu in this.menuData">
<el-submenu
:key="menu.url"
:index="menu.url"
v-if="menu.children && menu.children.length > 0 && !menu.hidden"
>
<template slot="title">
<img :src="require(`@/assets/menu/${menu.meta.icon}.png`)" alt="" />
<!-- <i :class="menu.meta.icon"></i> -->
<span slot="title">{{ menu.meta.title }}</span>
</template>
<menu-tree :menuData="menu.children"></menu-tree>
</el-submenu>
<el-menu-item
:key="menu.meta.url + 'u'"
:index="menu.meta.url"
v-else-if="!menu.hidden"
>
<img
:src="require(`@/assets/menu/${menu.meta.icon}.png`)"
alt=""
v-if="menu.meta.icon"
/>
<span slot="title">{{ menu.meta.title }}</span>
</el-menu-item>
</template>
</div>
</template>
<script>
export default {
props: ['menuData'],
name: 'MenuTree'
}
</script>
- 引入子组件,渲染菜单
<template>
<div class="container">
<el-aside
ref="menuContainer"
class="menu-container"
:class="isCollapse ? 'menu-container-collapse' : ''"
>
<!-- 实现菜单多级分类 -->
<el-menu
ref="elMenu"
:default-active="activeMenu"
@select="handleSelect"
:default-openeds="defaultOpenList"
:collapse="isCollapse"
class="common-scroll"
>
<!-- 引入组件 -->
<menu-tree :menuData="menuList"></menu-tree>
</el-menu>
</el-aside>
</div>
</template>
<script>
import MenuTree from './components/SubMenu.vue'
import { mapGetters } from 'vuex'
export default {
name: 'sideMenu',
components: {
MenuTree
},
data () {
return {
defaultOpenList: [],
activeMenu: ''
}
},
mounted () {
// 默认展开的菜单列表
this.defaultOpenList = [
'/project'
]
this.handleSelect(
this.$route.fullPath.slice(1, this.$route.fullPath.length)
)
},
computed: {
...mapGetters(['menuList', 'windowWidth']),
isCollapse: {
get () {
return this.$store.getters.isCollapse
},
set (val) {
this.$store.commit('setIsCollapse', val)
}
}
},
watch: {
'$route.path': {
this.activeMenu = val
},
immediate: true,
deep: true
}
},
methods: {
handleSelect (index, indexPath) {
if (index == 'home') {
this.$router.push(`/`)
} else {
if (indexPath) {
this.$router.push(indexPath[indexPath.length - 1])
} else {
this.$router.push(`/${index}`)
}
}
}
}
}
</script>
menuList 中的值是这样的
menuList = [
{
path: 'home',
name: 'Home',
meta: {
title: '总览',
icon: 'home',
url: '/home'
},
url: '/home'
},
{
path: '/project',
meta: {
title: '在线监测',
icon: 'project',
},
children: [
{
path: 'project',
name: 'Project',
meta: {
title: '项目',
url: '/project/project'
},
url: '/project/project'
},
....
]
}
]
- activeMenu – 实现菜单选中且高亮default-active绑定的值,为渲染路由时绑定的 index
- defaultOpenList – 默认展开菜单的 Url 集合default-openeds绑定的值
但是在实际开发中还是会遇到一个问题:
当我们菜单过多过长时,滚动到某个菜单选中查看其页面,但当我们刷新页面时,页面虽然仍旧显示的是之前访问的页面,但是菜单已经回滚到了顶部,导致我们看不到选中的菜单,不得不又重新滚动查看,这样就做了很多没有必要的操作,也是不符合用户的预期。
scrollToActiveMenu () {
// 获取当前选中菜单元素
const menu = document.querySelector(`.el-menu-item.is-active`)
if (menu) {
// 将菜单滚动到可见区域
menu.scrollIntoView({ behavior: 'smooth' })
}
}