vue3 el-menu,el-tabs实现联动

页面整体效果图

1.页面布局

        首先布置好布局,页面的整体效果如下:

<template>
  <div class="box">
    <div class="box__left">
      <!-- 侧边菜单栏标签 -->
      <index-sidebar></index-sidebar>
      <!-- 侧边菜单栏标签 -->
    </div>
    <div class="box__right">
      <index-header></index-header>
      <!-- tabs标签 -->
      <index-tabs></index-tabs>
      <!-- tabs标签 -->
    </div>
  </div>
</template>

<script setup lang="ts">

</script>

<style scoped lang="scss">
@import '@/assets/css/base.scss';
.box{
  display: flex;
  &__left{
    width: 110px;
  }
  &__right{
    flex: 1;
  }
}
</style>

 2.侧边栏用el-menu标签,标签的选中状态与属性default-active有关,tabs标签用el-tabs,选中转态态与editableTabsValue有关,实现关联就是将2个属性的值相同即可。由于页面是封装成了子组件,所以这里el-tabs的标签属性editableTabs,editableTabsValue在pinia中进行状态管理,在进行引入。

import { defineStore } from  'pinia'
import {ref} from 'vue'
export const tabsStore = defineStore('tabs',()=>{
  const editableTabsValue =ref('home')
  const editableTabs = ref([
    {
      title: '工作台',
      name: 'home',
    },
  ])

  return {editableTabs,editableTabsValue}
})

3.在index-tabs.vue中,映入Pinia里的editableTabs,editableTabsValue,在removeTab事件中不希望移除第一个标签,先进行判断是否点击的是第一个即可,changTab事件点击跳转对应路由

<template>
  <div class="tabs">
    <el-tabs v-model="tab.editableTabsValue" type="card" class="demo-tabs" closable @tab-remove="removeTab" @tab-change="changeTab">
 
      <el-tab-pane  v-for="item in tab.editableTabs" :key="item.name" :label="item.title" :name="item.name">
        <keep-alive><router-view ></router-view></keep-alive>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>
<script lang="ts" setup>
import { ref} from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
import { tabsStore } from '@/stores/tabs.js'
const tab = tabsStore()

const removeTab = (targetName: string) => {
  if (targetName !== 'home') {//判断点击是否为工作台
    if (tab.editableTabsValue === targetName) {
      tab.editableTabs.forEach((tabs, index) => {
        if (tabs.name === targetName) {
          const nextTab = tab.editableTabs[index + 1] || tab.editableTabs[index - 1]
          if (nextTab) {
            router.push(nextTab.name)
          }
        }
      })
    }
    //过滤掉当前点击的tab标签
    tab.editableTabs = tab.editableTabs.filter((tab) => tab.name !== targetName)
  }

}
const changeTab = (targetName: string)=>{
  router.push(targetName)
}


</script>

4.在index-sidebar.vue中,先设置好el-menu的router属性,对应的index填上跳转的路由。default-active这里命名为Eindex,在,通过watch监听事件监听路由的变化,先将tab.editableTabs中的title值取出为一个数组,再对当前route.name进行判断是否存在,不存在则添加到tab.editableTabs数组中。Eindex的值与当前路由名字保持一致即可实现tabs和menu的互联。

5.当刷新页面时,路由会只保留第一个tab标签,可能与当前路由对应不上,需要在onMounted中判断当前路由,若不等于第一个标签的路由,则tab.editableTabs数组添加该值,Eindex值也要跟当前路由保持一致。

<template>
  <div class="sidebar">
    <!-- logo -->
    <div class="sidebar__logo">logo</div>
    <!-- logo--end -->
    <!-- 侧边导航 -->
    <el-menu class="el-menu-vertical-demo" :default-active="Eindex" unique-opened router>
      <el-sub-menu index="1">
        <template #title>
          <el-icon>
            <location />
          </el-icon>
          <span>影片</span>
        </template>
        <el-menu-item-group title="影片">
          <el-menu-item  index="film-management" name="影片管理">影片管理</el-menu-item>
          <el-menu-item  index="film-types">影片分类</el-menu-item>
        </el-menu-item-group>
      </el-sub-menu>

      <el-sub-menu index="2">
        <template #title>
          <el-icon>
            <location />
          </el-icon>
          <span>影院</span>
        </template>
        <el-menu-item-group title="影院">
          <el-menu-item index="cinema-management">影院管理</el-menu-item>
        </el-menu-item-group>
      </el-sub-menu>

      <el-sub-menu index="3">
        <template #title>
          <el-icon>
            <location />
          </el-icon>
          <span>用户</span>
        </template>
        <el-menu-item-group title="用户">
          <el-menu-item index="user-management">用户管理</el-menu-item>
        </el-menu-item-group>
      </el-sub-menu>
    </el-menu>
    <!-- 侧边导航--end -->
  </div>
</template>

<script setup lang="ts">
import {useRouter,useRoute} from 'vue-router'
const router = useRouter()
const route = useRoute()
import {watch,ref, onMounted} from 'vue'
import { tabsStore } from '@/stores/tabs.js'
const tab = tabsStore()
const Eindex = ref()
onMounted(()=>{
  
  if(route.name!=='home'){
    tab.editableTabs.push({
      title: route.meta.title,
      name: route.name,
    })
    tab.editableTabsValue = route.name
    Eindex.value=route.name
  }
})
watch(route,()=>{
  const arr =[]
  tab.editableTabs.forEach(item => {
    arr.push(item.title)
  });
  const res = arr.indexOf(route.meta.title)
  if(res==-1){
      tab.editableTabs.push({
      title: route.meta.title,
      name: route.name,
    })
  }
  tab.editableTabsValue = route.name
  Eindex.value=route.name
})
</script>

 

转载请说明出处内容投诉
CSS教程_站长资源网 » vue3 el-menu,el-tabs实现联动

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买