您现在的位置是:首页 > 技术教程 正文

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

admin 阅读: 2024-04-01
后台-插件-广告管理-内容页头部广告(手机)

页面整体效果图

1.页面布局

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

  1. <template>
  2. <div class="box">
  3. <div class="box__left">
  4. <index-sidebar>index-sidebar>
  5. div>
  6. <div class="box__right">
  7. <index-header>index-header>
  8. <index-tabs>index-tabs>
  9. div>
  10. div>
  11. template>
  12. <script setup lang="ts">
  13. script>
  14. <style scoped lang="scss">
  15. @import '@/assets/css/base.scss';
  16. .box{
  17. display: flex;
  18. &__left{
  19. width: 110px;
  20. }
  21. &__right{
  22. flex: 1;
  23. }
  24. }
  25. style>

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

  1. import { defineStore } from 'pinia'
  2. import {ref} from 'vue'
  3. export const tabsStore = defineStore('tabs',()=>{
  4. const editableTabsValue =ref('home')
  5. const editableTabs = ref([
  6. {
  7. title: '工作台',
  8. name: 'home',
  9. },
  10. ])
  11. return {editableTabs,editableTabsValue}
  12. })

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

  1. <template>
  2. <div class="tabs">
  3. <el-tabs v-model="tab.editableTabsValue" type="card" class="demo-tabs" closable @tab-remove="removeTab" @tab-change="changeTab">
  4. <el-tab-pane v-for="item in tab.editableTabs" :key="item.name" :label="item.title" :name="item.name">
  5. <keep-alive><router-view >router-view>keep-alive>
  6. el-tab-pane>
  7. el-tabs>
  8. div>
  9. template>
  10. <script lang="ts" setup>
  11. import { ref} from 'vue'
  12. import { useRouter } from 'vue-router'
  13. const router = useRouter()
  14. import { tabsStore } from '@/stores/tabs.js'
  15. const tab = tabsStore()
  16. const removeTab = (targetName: string) => {
  17. if (targetName !== 'home') {//判断点击是否为工作台
  18. if (tab.editableTabsValue === targetName) {
  19. tab.editableTabs.forEach((tabs, index) => {
  20. if (tabs.name === targetName) {
  21. const nextTab = tab.editableTabs[index + 1] || tab.editableTabs[index - 1]
  22. if (nextTab) {
  23. router.push(nextTab.name)
  24. }
  25. }
  26. })
  27. }
  28. //过滤掉当前点击的tab标签
  29. tab.editableTabs = tab.editableTabs.filter((tab) => tab.name !== targetName)
  30. }
  31. }
  32. const changeTab = (targetName: string)=>{
  33. router.push(targetName)
  34. }
  35. 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值也要跟当前路由保持一致。

  1. <template>
  2. <div class="sidebar">
  3. <div class="sidebar__logo">logodiv>
  4. <el-menu class="el-menu-vertical-demo" :default-active="Eindex" unique-opened router>
  5. <el-sub-menu index="1">
  6. <template #title>
  7. <el-icon>
  8. <location />
  9. el-icon>
  10. <span>影片span>
  11. template>
  12. <el-menu-item-group title="影片">
  13. <el-menu-item index="film-management" name="影片管理">影片管理el-menu-item>
  14. <el-menu-item index="film-types">影片分类el-menu-item>
  15. el-menu-item-group>
  16. el-sub-menu>
  17. <el-sub-menu index="2">
  18. <template #title>
  19. <el-icon>
  20. <location />
  21. el-icon>
  22. <span>影院span>
  23. template>
  24. <el-menu-item-group title="影院">
  25. <el-menu-item index="cinema-management">影院管理el-menu-item>
  26. el-menu-item-group>
  27. el-sub-menu>
  28. <el-sub-menu index="3">
  29. <template #title>
  30. <el-icon>
  31. <location />
  32. el-icon>
  33. <span>用户span>
  34. template>
  35. <el-menu-item-group title="用户">
  36. <el-menu-item index="user-management">用户管理el-menu-item>
  37. el-menu-item-group>
  38. el-sub-menu>
  39. el-menu>
  40. div>
  41. template>
  42. <script setup lang="ts">
  43. import {useRouter,useRoute} from 'vue-router'
  44. const router = useRouter()
  45. const route = useRoute()
  46. import {watch,ref, onMounted} from 'vue'
  47. import { tabsStore } from '@/stores/tabs.js'
  48. const tab = tabsStore()
  49. const Eindex = ref()
  50. onMounted(()=>{
  51. if(route.name!=='home'){
  52. tab.editableTabs.push({
  53. title: route.meta.title,
  54. name: route.name,
  55. })
  56. tab.editableTabsValue = route.name
  57. Eindex.value=route.name
  58. }
  59. })
  60. watch(route,()=>{
  61. const arr =[]
  62. tab.editableTabs.forEach(item => {
  63. arr.push(item.title)
  64. });
  65. const res = arr.indexOf(route.meta.title)
  66. if(res==-1){
  67. tab.editableTabs.push({
  68. title: route.meta.title,
  69. name: route.name,
  70. })
  71. }
  72. tab.editableTabsValue = route.name
  73. Eindex.value=route.name
  74. })
  75. script>

 

标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索