Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

Let’s look at the implementation

Implementation approach

  1. el-menuusevue-router Mode to index for route jump, current active menu:default-active="$route.path", this will default to the current routing path highlighting menu options, to resolve the refresh situation such as highlighting problems, main code
    <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>
Copy the code
  1. el-tabsthe:value(Check the TABname) by$route.pathTo control,el-tabsThe data structure of[{title: 'home', path: '/home',name:' home'}](VUEX management). If you click to redirect a route through path and delete the current page, you need to obtain the path of the next TAB page before redirecting.
<template>
  <el-tabs type="card"
    :value="$route.path"
    @tab-click="tabClick"
    closable
    class="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'
export default {
  name: 'TabsNav',
  data () {
    return {
    }
  },
  created () {

  },
  watch: {

  },
  mounted () {
    // Listen to refresh, save data to 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) {
      // Delete the TAB
      if (action === 'remove') {
        if (targetPath === '/home') return
        let nextTab = {}
        // Find the next route
        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)
        // If the current page is deleted, jump
        targetPath === this.$route.path && this.$router.push(nextTab.path)
      }
    },
    tabClick ({ name }) {
      if (name === this.$route.path) return
      this.$router.push(name)
    }
  }
}
</script>
Copy the code
  1. usevuexManage TAB page state
import {
  getSessionTabsValue
} from '@/utils/storage'

/ / initialization
const initTabValue = getSessionTabsValue() || {
  tabsValue: [{
    title: 'home'.path: '/home'.name: 'Home'}}]const tabsNav = {
  state: () = > (initTabValue),
  mutations: {
    /** * delete TAB *@param {*} state
     * @param {*} targetPath* /
    REMOVE_TABS_VALUE(state, targetPath) {
      state.tabsValue = state.tabsValue.filter(item= >item.path ! == targetPath) },/** * Add tabs to the MenuItem component@param {*} state
     * @param {*} data* /
    ADD_TABS_VALUE(state, data) {
      // Check whether it already exists
      const isExist = state.tabsValue.some(item= > item.path === data.path)
      // If there is no add
      if(! isExist) { state.tabsValue.push(data) } },/** * Initializes the data, which is called when logging out, otherwise the old label data will remain after switching users *@param {*} state* /
    RESET_TABS_VALUE(state) {
      state = initTabValue
    }

  },
  actions: {},
  getters: {}}export default tabsNav
Copy the code
  1. When listening for route rehops, check whether the label management is used. If yes, check whether the current route has been addedtabsValue(On mutations, the ADD_TABS_VALUE judgment)
// Route object data structure
{
    path: '/home'.name: 'Home'.component: Home,
    meta: {
      title: 'home'.isTabsPage: true
    }
  }

router.beforeEach((to, from, next) = > {
  if (to.meta.title) { // If the title is set, set the title after interception
    document.title = to.meta.title
  }

  if(to.path ! = ='/login') {
    if(! store.getters.isLogin) { Message.error('Please log in first')
      next('/login')
      return
    }
    // Determine if you want to add it to the tabs TAB
    if (to.meta.isTabsPage) {
      const tabsItem = {
        name: to.name,
        title: to.meta.title,
        path: to.path
      }
      store.commit('ADD_TABS_VALUE', tabsItem)
    }
  }
  next()
})
Copy the code
  1. usekeep-aliveCaches pages in tabs
 <el-main>
    <transition name="fade-transform" mode="out-in">
       <keep-alive :include="cachedViews">
         	<router-view></router-view>
       </keep-alive>
    </transition>
</el-main>

cachedViews () {
     return this.$store.state.tabsNav.tabsValue.map(item= > item.name)
}
Copy the code

This achieves the above effect, but there are many areas that can be optimized, and the coupling is a bit high…