vue菜單欄聯(lián)動內(nèi)容頁面tab的實現(xiàn)示例
一、需求
需要實現(xiàn)效果:左側(cè)菜單欄與右側(cè)內(nèi)容部分聯(lián)動,當(dāng)點擊左側(cè)的菜單,右側(cè)會展示對應(yīng)的tab,沒有點擊時,不展示(如剛進入頁面沒有點擊菜單,則沒有tab);點擊后沒有關(guān)閉tab再打開其他菜單(如測試項目2),則測試項目2的tab高亮為選中狀態(tài)。
實現(xiàn)效果:
二、整體實現(xiàn)思路
1.環(huán)境:vue、element-ui
2.首先,在el-tab-pane中,是展示的tab(如上圖的測試項目1、測試項目2)。因此我們創(chuàng)建了一個數(shù)組activeTabs來儲存tab的信息。
- :label="getTabTitle(route.path)" 對應(yīng)的則是tab展示的標(biāo)題內(nèi)容,我用了一個方法getTabTitle獲取路由對應(yīng)的標(biāo)題。
- :name="route.meta.title" 則是與el-tabs下的 v-model="activeName"相對應(yīng),如果name的值與v-model的值一樣,則表示當(dāng)前選中的tab。
- 代碼中,
v-model="activeName"
用于控制el-tabs
組件的當(dāng)前活動標(biāo)簽,而:name="route.meta.title"
用于為每個標(biāo)簽指定一個唯一的名稱,這樣就可以通過這個名稱來確定當(dāng)前選中的標(biāo)簽。通過這兩個指令影響到同一個數(shù)據(jù)(例如activeName
和route.meta.title
),以達到實現(xiàn)標(biāo)簽切換的效果。 - 當(dāng)前選中的狀態(tài)由
@tab-click="selectTab"
事件處理器決定。當(dāng)點擊一個標(biāo)簽時(tab-click
事件),會觸發(fā)selectTab
方法。在selectTab
方法中,this.activeName
屬性根據(jù)點擊的標(biāo)簽的meta.title
進行更新。v-model="activeName"
會自動反映這個變化,使得el-tabs
組件根據(jù)activeName
的值來確定哪個標(biāo)簽是當(dāng)前選中的,從而產(chǎn)生高亮效果。 - @edit="handleTabsEdit"是為了對tab做一些操作,點擊 tabs 的新增按鈕或 tab 被關(guān)閉后觸發(fā)。
值得注意的是v-model="activeName"、selectTab、 :name="route.meta.title"幾個的對應(yīng)關(guān)系,以及其數(shù)據(jù)結(jié)構(gòu)。
<el-tabs v-model="activeName" editable @edit="handleTabsEdit" @tab-click="selectTab" > <el-tab-pane v-for="(route, index) in activeTabs" :key="index" :label="getTabTitle(route.path)" :name="route.meta.title" > </el-tab-pane> </el-tabs>
三、我遇到的問題
1.數(shù)據(jù)結(jié)構(gòu)問題,一開始拿到的只是name或label、path,這樣是不行的,最好還是拿到當(dāng)前對應(yīng)菜單欄的完整router,方便我們操作。
2.點擊菜單欄對應(yīng)的tab沒有高亮但內(nèi)容顯示了
3.點擊關(guān)閉tab,tab關(guān)閉了但下面的內(nèi)容沒有關(guān)閉,沒有跳轉(zhuǎn)到下一個剩余tab的內(nèi)容。
4.點擊tab之間相互切換,功能是正常的頁面內(nèi)容切換,但存在問題tab沒有高亮,有時候要點擊兩次才會高亮,判段問題是出在沒有更新調(diào)用selectTab。
四、具體代碼
<template> <section class="app-main"> <el-tabs v-model="activeName" editable @edit="handleTabsEdit" @tab-click="selectTab" > <el-tab-pane v-for="(route, index) in activeTabs" :key="index" :label="getTabTitle(route.path)" :name="route.meta.title" > </el-tab-pane> </el-tabs> <transition name="fade-transform" mode="out-in"> //展示具體頁面內(nèi)容 <content //自定義組件 > <div class="router-inner-container"> <router-view v-show="activeName" :key="key" /> //v-show="activeName"非常重要,注意不要用v-if,用來與當(dāng)前tab對應(yīng),即關(guān)閉tab也關(guān)閉當(dāng)前內(nèi)容。 </div> </content> </transition> </section> </template> <script> import { mapGetters } from 'vuex'; //引入vuex,來拿到我的所有菜單路由 export default { name: 'AppMain', props: { noTag: { type: Boolean, default: false }, noMap: { type: Boolean, default: false } }, data() { return { activeName: null, // 默認選中第一個 tab activeTabs: [] // 存儲當(dāng)前顯示的 tab }; }, computed: { ...mapGetters(['sidebar', 'sidebarRouters']), //菜單所有路由sidebarRouters key() { return this.$route.path; }, isStatisticsView() { if (this.$route.path == '/home/index') { return true; } else { return false; } } }, methods: { selectTab(tab, event) { if (Array.isArray(tab) && tab.length > 0) { //由于數(shù)據(jù)結(jié)構(gòu)問題做的判段,拿到activeName this.activeName = tab[0].meta.title; } else if (typeof tab === 'object' && tab.meta) { this.activeName = tab.meta.title; } else if (Array.isArray(tab) && !tab.length > 0) { this.activeName = ''; //當(dāng)所有tab都關(guān)閉時,關(guān)閉所有內(nèi)容,否則頁面會tab都關(guān)閉了,但還有最后一個關(guān)閉的tab的頁面內(nèi)容。 } }, handleTabsEdit(targetName, action) { // 處理標(biāo)簽頁編輯事件 if (action === 'remove') { // 刪除標(biāo)簽頁 this.removeTab(targetName); } }, removeTab(targetName) { const tabs = this.activeTabs; const index = tabs.findIndex((tab) => tab.meta.title === targetName); if (index !== -1) { tabs.splice(index, 1); this.selectTab(tabs, event); //很重要,更新activeName,否則刪除后不會切換下一個對應(yīng)tab也不會切換頁面內(nèi)容 } }, updateActiveTabs() { const currentPath = this.$route; // 判斷對象是否在 activeTabs 中存在 const existsInTabs = this.activeTabs.some( (tab) => tab.hasOwnProperty('path') && tab.path === currentPath.path ); if (!existsInTabs) { // 如果當(dāng)前路由不在 activeTabs 中,將其添加進去 this.activeTabs.push(currentPath); } this.selectTab(currentPath, event); //很重要,更新activeName,否則切換菜單欄時對應(yīng)的tab不會高亮不會切換 }, findMatchingRoute(routes, targetPath) { //為了處理數(shù)組的 for (const route of routes) { if (route.path === targetPath) { return route; } if (route.children && route.children.length > 0) { const matchingChild = this.findMatchingRoute( route.children, targetPath ); if (matchingChild) { return matchingChild; } } } return null; }, getTabTitle(route) { // 根據(jù)路由信息獲取對應(yīng)的標(biāo)題 const matchingRoute = this.findMatchingRoute(this.sidebarRouters, route); return matchingRoute ? matchingRoute.meta.title : ''; }, findMatchingMenu(routes, targetTitle) { // 遞歸查找匹配的菜單項 for (const route of routes) { if (route.meta) { if (route.meta.title === targetTitle) { return route; } if (route.children && route.children.length > 0) { const matchingChild = this.findMatchingMenu( route.children, targetTitle ); if (matchingChild) { return matchingChild; } } } } return null; } }, mounted() {}, watch: { $route(to, from) { if (to && to.meta && !to.meta.noMap) { this.$nextTick(() => { this.$refs.jmap.resizeMap(); }); } // 更新 activeTabs this.updateActiveTabs(); }, activeName: { immediate: true, deep: true, handler(val, oldVal) { if (val && val !== oldVal) { const matchingMenu = this.findMatchingMenu(this.sidebarRouters, val); if (matchingMenu) { this.$router.push({ path: matchingMenu.path }); //切換tab時,切換路由來對應(yīng)想要頁面內(nèi)容 } } } } } }; </script> <style lang="scss"> .app-main { /*50 = navbar */ height: calc(100vh - 50px); width: 100%; position: relative; overflow: hidden; display: flex; flex-direction: column; background: #f3f3f3; &.no-header { height: 100vh; } } .fixed-header + .app-main { padding-top: 60px; } .single-layout { .app-main { padding: 0px; } } .map-style + .router-inner-container { position: absolute; } </style> <style lang="scss"> // fix css style bug in open el-dialog .el-popup-parent--hidden { .fixed-header { padding-right: 15px; } } .no-header { .float-panel { height: 100vh; } } </style>
到此這篇關(guān)于vue菜單欄聯(lián)動內(nèi)容頁面tab的實現(xiàn)示例的文章就介紹到這了,更多相關(guān)vue菜單欄聯(lián)動頁面tab內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue實現(xiàn)圖片下載點擊按鈕彈出本地窗口選擇自定義保存路徑功能
vue前端實現(xiàn)前端下載,并實現(xiàn)點擊按鈕彈出本地窗口,選擇自定義保存路徑,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2023-12-12