Vue 刷新页面实现自动选中上次的菜单以及将菜单滚动到可见区域

  1. 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
  1. 创建 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>
  1. 引入子组件,渲染菜单
<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' })
      }
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值