Tab page usage and bug resolution

The tab page is placed in the main
tab page el-tabs main attributes:
(1) editableTabsValue: Highlight the selected tab page (identified by name)
(2) editableTabs: tab page array (stores all tab page information), Attributes: name, title

<!--      标签页-->
      <el-tabs v-model="editableTabsValue" type="card" closable @tab-remove="removeTab" @tab-click="selectTab">
        <el-tab-pane
            v-for="(item, index) in editableTabs"
            :key="item.name"
            :label="item.title"
            :name="item.name"
        >
        </el-tab-pane>
      </el-tabs>

editableTabsValue, editableTabs are stored in store

1. Click the menu item to generate a new tab page

Click the menu item to generate a new tab. Before adding a new tab, check whether the tab array already contains the tab. If you already have the tab, you only need to select the tab.
Example:
insert image description here
Add the title and name of the menu item to the array of tabs via the click event addTabs

<el-menu-item index="/index" @click="addTabs({title:'首页',name:'/index'})">
        <i class="el-icon-s-home"></i>
        <span slot="title">首页</span>
</el-menu-item>
<el-menu-item :index="item.name" :route="{path:item.path}" v-for="item in menu.children" @click="addTabs(item)">
      <template slot="title">
           <i :class="item.icon"></i>
            <span>{
    
    {
    
    item.title}}</span>
      </template>
</el-menu-item>

The corresponding addTabs method in the store adds a new tab item and highlights it, that is, the selected state.

//添加标签页
        addTab(state,item){
    
    
            //当标签页数组中没有当前标签时才添加。
            let index = state.editableTabs.findIndex(e => e.name===item.name)
            if(index===-1){
    
    
                state.editableTabs.push({
    
    
                    title: item.title,
                    name: item.name
                })
            }
            //将新添加标签页激活:高亮
            state.editableTabsValue = item.name
        }

Because the tab page array editableTabs is dynamically updated, the editableTabsValue and editableTabs values ​​should be dynamically obtained in main. Implemented by computed.
as follows:

//动态监测变量值
  computed:{
    
    
    editableTabsValue: {
    
    
      get(){
    
    
        return this.$store.state.menus.editableTabsValue;
      },
      set(val){
    
    
        this.$store.state.menus.editableTabsValue = val;
      }
    },
    editableTabs:{
    
    
      get(){
    
    
        return this.$store.state.menus.editableTabs;
      },
      set(val){
    
    
        this.$store.state.menus.editableTabs = val;
      }
    }
  },

2. Click the tab item to achieve page jump

Add binding event @tab-click="selectTab"
tab section in tab

<el-tabs v-model="editableTabsValue" type="card" closable @tab-remove="removeTab" @tab-click="selectTab">
        <el-tab-pane
            v-for="(item, index) in editableTabs"
            :key="item.name"
            :label="item.title"
            :name="item.name"
        >

The page jump is realized by the route jump function selectTab.
The premise is that the name of the menu item must be the same as the name of the routing item.

//点击某个标签页实现路由跳转
    selectTab(target){
    
    
      //新知识点
      //this.$router.push()不仅可以通过path跳转,还可以通过name跳转
      this.$router.push({
    
    name:target.name}).catch(err => {
    
    
        console.log(err)
      })
    }

Detailed explanation of router.push() parameters

3、bug

bug1: When refreshing the page, the previously displayed tabs disappeared.
Reason: The data in the vuex store will be restored to default as the page refreshes.
Solution: Store editableTabs and editableTabsValue in the session.
When the page is refreshed, the information in vuex is saved in sessionStorage. When the page is loaded, the information in the session is read and loaded into the store.
Operate in App.vue

// 解决刷新页面后,页面path和页面内容不同bug
  created() {
    
    
    //在页面刷新时将vuex里面的信息保存在sessionStorage
    window.addEventListener("beforeunload",() => {
    
    
      sessionStorage.setItem("editableTabs",JSON.stringify(this.$store.state.menus.editableTabs))
      sessionStorage.setItem("editableTabsValue",this.$store.state.menus.editableTabsValue)
    })
    //页面加载时读取session中的信息,并加载到store中
    sessionStorage.getItem("editableTabsValue")&&this.$store.commit("getEditableTabsValue",sessionStorage.getItem("editableTabsValue"))
    sessionStorage.getItem("editableTabs")&&this.$store.commit("getEditableTabs",JSON.parse(sessionStorage.getItem("editableTabs")))

  },

Corresponding to the related functions in the store, getEditableTabsValue, getEditableTabs

//从session中获取editableTabsValue
        getEditableTabsValue(state,editableTabsValue){
    
    
            state.editableTabsValue = editableTabsValue
        },
        //从session中获取editableTabs
        getEditableTabs(state,editableTabs){
    
    
            state.editableTabs = editableTabs
        },

bug2: If a menu item is accessed directly through the url, and there is no relevant tab page information in the store and session, the tab page will be blank at this time. So add a monitoring watch to App.vue

//监控
  //当用户通过输入url访问界面时,此时store中和session中可能都没有该页面标签页的信息,这时就要通过watch解决
  //原理:在我们访问对应path之前,就把path对应的title、name加入到store中
  watch: {
    
    
    $route(to,from){
    
    
      //当我前往的路由路径不是login时,就把该路由信息加入到标签页数组中
      if(to.path !== '/login'){
    
    
        let obj  = {
    
    
          title: to.meta.title,
          name: to.name
        }
        this.$store.commit("addTab",obj)
      }
    }
  }

Note : route is used here.
Difference between route and router
bug3: After the user exits, the store information is not restored to the default

logout(){
    
    
      this.$axios.post('/logout').then(res => {
    
    
        //清除本地用户信息
        localStorage.clear()
        sessionStorage.clear()
        //清除store中token信息
        this.$store.commit("resetState");
        //清除store中的标签页信息
        this.$store.commit("resetEditableTabs")
        this.$store.commit("resetEditableTabsValue")
        router.push('/login')
      })
    },

Guess you like

Origin blog.csdn.net/weixin_43424325/article/details/121362490