vue+element-ui实现侧边菜单栏与标签页联动

2022年7月20日08:14:23

使用vue+element-ui实现侧边栏菜单el-menuel-tabs标签页联动效果

先看实现效果
vue+element-ui实现侧边菜单栏与标签页联动

实现思路

  1. el-menu使用vue-router的模式,以index进行路由跳转,当前激活菜单:default-active="$route.path",这样就会默认以当前路由路径高亮菜单选项,解决刷新等情况的高亮问题,主要代码
<el-menu:default-active="$route.path"class="el-menu-vertical-demo"
      background-color="#2f3640"
      text-color="#fff":style="{width:asideBarWidth}":width="asideBarWidth":collapse="$store.state.isCollapse":unique-opened="true":router="true"
      active-text-color="#409EFF"><menu-item v-for="item in menuData":key="item.path":item="item"/></el-menu>
  1. el-tabs:value(选中选项卡的name)也是由$route.path进行控制,el-tabs的数据结构是这样的:[{title: '首页',path: '/home',name: 'Home'}](vuex管理),当点击的通过path进行路由跳转,删除时,如果是删除当前页,则需要获取下一个标签页的路径,再进行跳转。
<template><el-tabs type="card":value="$route.path"
    @tab-click="tabClick"
    closableclass="my-tabs"
    @edit="handleTabsEdit"><el-tab-pane:key="item.path"
      v-for="(item) in tabsValue":label="item.title":name="item.path"></el-tab-pane></el-tabs></template><script>import{ mapState}from'vuex'import{ setSessionTabsValue}from'@/utils/storage'exportdefault{
  name:'TabsNav',data(){return{}},created(){},
  watch:{},mounted(){// 监听刷新,将数据保存到sessionStorage里
    window.addEventListener('beforeunload',this.setStorage)},destroyed(){
    window.removeEventListener('beforeunload',this.setStorage)},
  computed:{...mapState({
      tabsValue: state=> state.tabsNav.tabsValue})},
  methods:{setStorage(){
      console.log('setStorage')setSessionTabsValue(this.tabsValue)},handleTabsEdit(targetPath, action){// 删除选项卡if(action==='remove'){if(targetPath==='/home')returnlet nextTab={}// 找到下一个路由this.tabsValue.forEach((item, index)=>{if(item.path=== targetPath){
            nextTab=this.tabsValue[index+1]||this.tabsValue[index-1]}})this.$store.commit('REMOVE_TABS_VALUE', targetPath)// 如果删除的是当前页,则进行跳转
        targetPath===this.$route.path&&this.$router.push(nextTab.path)}},tabClick({ name}){if(name===this.$route.path)returnthis.$router.push(name)}}}</script>
  1. 使用vuex管理标签页的状态
import{
  getSessionTabsValue}from'@/utils/storage'// 初始化const initTabValue=getSessionTabsValue()||{
  tabsValue:[{
    title:'首页',
    path:'/home',
    name:'Home'}]}const tabsNav={
  state:()=>(initTabValue),
  mutations:{/**
     * 删除标签页
     * @param {*} state
     * @param {*} targetPath
     */REMOVE_TABS_VALUE(state, targetPath){
      state.tabsValue= state.tabsValue.filter(item=> item.path!== targetPath)},/**
     * 添加标签页,在MenuItem组件触发
     * @param {*} state
     * @param {*} data
     */ADD_TABS_VALUE(state, data){// 判断是否已经存在const isExist= state.tabsValue.some(item=> item.path=== data.path)// 如果不存在添加if(!isExist){
        state.tabsValue.push(data)}},/**
     * 初始化数据,在注销时调用,不然切换用户后还是旧标签数据
     * @param {*} state
     */RESET_TABS_VALUE(state){
      state= initTabValue}},
  actions:{},
  getters:{}}exportdefault tabsNav
  1. 监听路由跳转,即路由跳转时,判断是否使用标签页管理,如果是,再判断当前路由是否已经加入tabsValue(在mutations的ADD_TABS_VALUE判断)
// 路由对象数据结构{
    path:'/home',
    name:'Home',
    component: Home,
    meta:{
      title:'首页',
      isTabsPage:true}}

router.beforeEach((to,from, next)=>{if(to.meta.title){// 如果设置标题,拦截后设置标题
    document.title= to.meta.title}if(to.path!=='/login'){if(!store.getters.isLogin){
      Message.error('请先登录')next('/login')return}// 判断是否需要添加到tabs标签if(to.meta.isTabsPage){const tabsItem={
        name: to.name,
        title: to.meta.title,
        path: to.path}
      store.commit('ADD_TABS_VALUE', tabsItem)}}next()})
  1. 使用keep-alive对在标签页的页面进行缓存
<el-main><transition name="fade-transform" mode="out-in"><keep-alive:include="cachedViews"><router-view></router-view></keep-alive></transition></el-main>cachedViews(){returnthis.$store.state.tabsNav.tabsValue.map(item=> item.name)}

这样就实现了上面的效果,但是还有许多地方可以优化,并且耦合性有点高…

  • 作者:代码打太久会头疼
  • 原文链接:https://blog.csdn.net/weixin_43693458/article/details/107717727
    更新时间:2022年7月20日08:14:23 ,共 3313 字。