ElementPlus 标签页和路由的组合使用

文章描述了一个使用Vue.js和VueRouter构建的网站,左侧导航栏通过点击选项在右侧创建并切换标签页显示内容,同时管理路由和标签的增删操作。
摘要由CSDN通过智能技术生成

目标:左侧导航区 右侧为展示区 点击导航区的某一项 右侧会新建一个标签页 展示内容 标签页之间可以点击切换 可以关闭除首页的其他标签页

目的效果如图

<el-main style="background-color: #ecf5ff;">
    <Tab></Tab>
    <RouterView></RouterView>
</el-main>

以下为Tab.vue 思路就是标签页的组件记录路由的path 被选中就将对应的path push到路由器里 将<RouteView/>的内容替换

<template>
    <el-tabs v-model="activeTab" @tab-change="tabChange" @tab-remove="tabRemove">
        <el-tab-pane v-for="item in tabList" :key="item.path" :label="item.title" :name="item.path"
            :closable="item.path != '/'">
        </el-tab-pane>
    </el-tabs>
</template>

<script lang="ts" setup>
import { ref, reactive } from 'vue'
import { useRoute, useRouter } from 'vue-router';

interface TabType {
    'title': string,
    'path': string
}

const route = useRoute()
const router = useRouter()
const activeTab = ref(route.path)
const tabList = reactive([
    {
        title: '首页',
        path: '/'
    }
])

//点击标签导致activeTab改变时触发
function tabChange(tab: string) {
    console.log('tabChange')
    router.push(tab)
    activeTab.value = tab
}


//添加路由 添加到标签页
function addTab(tab: TabType) {
    const index = tabList.findIndex((item) => item.path == tab.path)
    //选中的菜单项目前没有在标签页中 需要添加到标签页中
    if (index == -1) {
        tabList.push(tab)
    }
}

//点击菜单导致路由变化 路由变化之前使用这个全局守卫 
router.beforeEach((to) => {
    activeTab.value = to.path
    addTab({
        title: to.meta.title as string,
        path: to.path
    })
})


function tabRemove(targetTab: string) {
    let targetIndex: number = 0 //要关闭的tab的index    

    //先找到要删除的
    tabList.forEach((tab, index) => {
        if (tab.path == targetTab) {
            targetIndex = index
        }
    })
    //要关闭的是当前活跃的tab
    if (activeTab.value == targetTab) {
        const nextTab = tabList[targetIndex - 1] || tabList[targetIndex + 1]
        activeTab.value = nextTab.path
        router.push(activeTab.value)
    }
    tabList.splice(targetIndex, 1)
    
}
</script>

以下为route/index.ts

import { createRouter, createWebHistory } from "vue-router";
import CmTrendCodeList from "@/views/CmTrendCodeList.vue";
import LeaseList from "@/views/Lease/LeaseList.vue";
import Home from '@/views/Home.vue'

const router = createRouter({
    history: createWebHistory(),
    routes: [
        {
            path: '/CmTrendCode',
            component: CmTrendCodeList,
            meta: {
                title: '动态代码'
            }
        },
        {
            path: '/LeaseList',
            component: LeaseList,
            meta: {
                title: '租箱协议'
            }
        },
        {
            path: '/',
            component: Home,
            meta: {
                title: '首页'
            }
        }
    ]

})

export default router

参考了https://blog.csdn.net/samate6666/article/details/126950343
但不同的是 我使用的是router.beforeEach()这个全局前置守卫 而不是onBeforeRouterUpdate() 我个人理解是onBeforeRouteUpdate()、beforeRouteUpdate()这些是组件内守卫 需要在组件内使用 就是到时候去替换<RouteView/>的那些组件 不然会有警告:App.vue:13  [Vue Router warn]: No active route record was found when calling `onBeforeRouteUpdate()`. Make sure you call this function inside a component child of <router-view>. Maybe you called it inside of App.vue?

被这个问题折磨了很久 去看了以下官方文档 发现onBeforeRouteUpdate()不能解决我的问题 也可能是我菜 觉得beforeEach()挺合适 如果觉得有帮助点个赞趴 谢谢

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值