最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue菜單欄聯(lián)動(dòng)內(nèi)容頁(yè)面tab的實(shí)現(xiàn)示例

 更新時(shí)間:2024年01月19日 09:23:23   作者:coinisi_li  
本文主要介紹了vue菜單欄聯(lián)動(dòng)內(nèi)容頁(yè)面tab的實(shí)現(xiàn)示例,左側(cè)菜單欄與右側(cè)內(nèi)容部分聯(lián)動(dòng),當(dāng)點(diǎn)擊左側(cè)的菜單,右側(cè)會(huì)展示對(duì)應(yīng)的tab,具有一定的參考價(jià)值,感興趣的可以了解一下

一、需求

需要實(shí)現(xiàn)效果:左側(cè)菜單欄與右側(cè)內(nèi)容部分聯(lián)動(dòng),當(dāng)點(diǎn)擊左側(cè)的菜單,右側(cè)會(huì)展示對(duì)應(yīng)的tab,沒(méi)有點(diǎn)擊時(shí),不展示(如剛進(jìn)入頁(yè)面沒(méi)有點(diǎn)擊菜單,則沒(méi)有tab);點(diǎn)擊后沒(méi)有關(guān)閉tab再打開(kāi)其他菜單(如測(cè)試項(xiàng)目2),則測(cè)試項(xiàng)目2的tab高亮為選中狀態(tài)。

實(shí)現(xiàn)效果:

二、整體實(shí)現(xiàn)思路

1.環(huán)境:vue、element-ui

2.首先,在el-tab-pane中,是展示的tab(如上圖的測(cè)試項(xiàng)目1、測(cè)試項(xiàng)目2)。因此我們創(chuàng)建了一個(gè)數(shù)組activeTabs來(lái)儲(chǔ)存tab的信息。

  • :label="getTabTitle(route.path)" 對(duì)應(yīng)的則是tab展示的標(biāo)題內(nèi)容,我用了一個(gè)方法getTabTitle獲取路由對(duì)應(yīng)的標(biāo)題。
  • :name="route.meta.title" 則是與el-tabs下的 v-model="activeName"相對(duì)應(yīng),如果name的值與v-model的值一樣,則表示當(dāng)前選中的tab。
  • 代碼中,v-model="activeName" 用于控制 el-tabs 組件的當(dāng)前活動(dòng)標(biāo)簽,而 :name="route.meta.title" 用于為每個(gè)標(biāo)簽指定一個(gè)唯一的名稱(chēng),這樣就可以通過(guò)這個(gè)名稱(chēng)來(lái)確定當(dāng)前選中的標(biāo)簽。通過(guò)這兩個(gè)指令影響到同一個(gè)數(shù)據(jù)(例如 activeName 和 route.meta.title),以達(dá)到實(shí)現(xiàn)標(biāo)簽切換的效果。
  • 當(dāng)前選中的狀態(tài)由 @tab-click="selectTab" 事件處理器決定。當(dāng)點(diǎn)擊一個(gè)標(biāo)簽時(shí)(tab-click 事件),會(huì)觸發(fā) selectTab 方法。在 selectTab 方法中,this.activeName 屬性根據(jù)點(diǎn)擊的標(biāo)簽的 meta.title 進(jìn)行更新。v-model="activeName" 會(huì)自動(dòng)反映這個(gè)變化,使得 el-tabs 組件根據(jù) activeName 的值來(lái)確定哪個(gè)標(biāo)簽是當(dāng)前選中的,從而產(chǎn)生高亮效果。
  •  @edit="handleTabsEdit"是為了對(duì)tab做一些操作,點(diǎn)擊 tabs 的新增按鈕或 tab 被關(guān)閉后觸發(fā)。

值得注意的是v-model="activeName"、selectTab、 :name="route.meta.title"幾個(gè)的對(duì)應(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>

三、我遇到的問(wèn)題

1.數(shù)據(jù)結(jié)構(gòu)問(wèn)題,一開(kāi)始拿到的只是name或label、path,這樣是不行的,最好還是拿到當(dāng)前對(duì)應(yīng)菜單欄的完整router,方便我們操作。

2.點(diǎn)擊菜單欄對(duì)應(yīng)的tab沒(méi)有高亮但內(nèi)容顯示了

3.點(diǎn)擊關(guān)閉tab,tab關(guān)閉了但下面的內(nèi)容沒(méi)有關(guān)閉,沒(méi)有跳轉(zhuǎn)到下一個(gè)剩余tab的內(nèi)容。

4.點(diǎn)擊tab之間相互切換,功能是正常的頁(yè)面內(nèi)容切換,但存在問(wèn)題tab沒(méi)有高亮,有時(shí)候要點(diǎn)擊兩次才會(huì)高亮,判段問(wèn)題是出在沒(méi)有更新調(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">  //展示具體頁(yè)面內(nèi)容
      <content   //自定義組件
      >
        <div class="router-inner-container">
          <router-view v-show="activeName" :key="key" /> //v-show="activeName"非常重要,注意不要用v-if,用來(lái)與當(dāng)前tab對(duì)應(yīng),即關(guān)閉tab也關(guān)閉當(dāng)前內(nèi)容。
        </div>
      </content>
    </transition>
  </section>
</template>

<script>
import { mapGetters } from 'vuex'; //引入vuex,來(lái)拿到我的所有菜單路由

export default {
  name: 'AppMain',
  props: {
    noTag: {
      type: Boolean,
      default: false
    },
    noMap: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      activeName: null, // 默認(rèn)選中第一個(gè) tab
      activeTabs: [] // 存儲(chǔ)當(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)問(wèn)題做的判段,拿到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)閉時(shí),關(guān)閉所有內(nèi)容,否則頁(yè)面會(huì)tab都關(guān)閉了,但還有最后一個(gè)關(guān)閉的tab的頁(yè)面內(nèi)容。
      }
    },
    handleTabsEdit(targetName, action) {
      // 處理標(biāo)簽頁(yè)編輯事件
      if (action === 'remove') {
        // 刪除標(biāo)簽頁(yè)
        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,否則刪除后不會(huì)切換下一個(gè)對(duì)應(yīng)tab也不會(huì)切換頁(yè)面內(nèi)容
      }
    },
    updateActiveTabs() {
      const currentPath = this.$route;
      // 判斷對(duì)象是否在 activeTabs 中存在
      const existsInTabs = this.activeTabs.some(
        (tab) => tab.hasOwnProperty('path') && tab.path === currentPath.path
      );
      if (!existsInTabs) {
        // 如果當(dāng)前路由不在 activeTabs 中,將其添加進(jìn)去
        this.activeTabs.push(currentPath);
      }
      this.selectTab(currentPath, event); //很重要,更新activeName,否則切換菜單欄時(shí)對(duì)應(yīng)的tab不會(huì)高亮不會(huì)切換
    },
    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ù)路由信息獲取對(duì)應(yīng)的標(biāo)題
      const matchingRoute = this.findMatchingRoute(this.sidebarRouters, route);
      return matchingRoute ? matchingRoute.meta.title : '';
    },
    findMatchingMenu(routes, targetTitle) {
      // 遞歸查找匹配的菜單項(xiàng)
      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時(shí),切換路由來(lái)對(duì)應(yīng)想要頁(yè)面內(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)動(dòng)內(nèi)容頁(yè)面tab的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)vue菜單欄聯(lián)動(dòng)頁(yè)面tab內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue中加載天地圖的離線(xiàn)地圖基本步驟

    Vue中加載天地圖的離線(xiàn)地圖基本步驟

    這篇文章主要給大家介紹了關(guān)于Vue中加載天地圖的離線(xiàn)地圖的基本步驟,Vue天地圖離線(xiàn)地圖是指基于Vue框架開(kāi)發(fā)的應(yīng)用程序,使用天地圖離線(xiàn)地圖服務(wù)提供商提供的地圖數(shù)據(jù),可以在沒(méi)有網(wǎng)絡(luò)的情況下使用地圖功能,需要的朋友可以參考下
    2023-10-10
  • Vue響應(yīng)式原理模擬實(shí)現(xiàn)原理探究

    Vue響應(yīng)式原理模擬實(shí)現(xiàn)原理探究

    這篇文章主要介紹了Vue響應(yīng)式原理,響應(yīng)式就是當(dāng)對(duì)象本身(對(duì)象的增刪值)或者對(duì)象屬性(重新賦值)發(fā)生了改變的時(shí)候,就會(huì)運(yùn)行一些函數(shù),最常見(jiàn)的示render函數(shù)
    2022-09-09
  • 使用vuex的時(shí)候,出現(xiàn)this.$store為undefined問(wèn)題

    使用vuex的時(shí)候,出現(xiàn)this.$store為undefined問(wèn)題

    這篇文章主要介紹了使用vuex的時(shí)候,出現(xiàn)this.$store為undefined問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • 解決element UI 自定義傳參的問(wèn)題

    解決element UI 自定義傳參的問(wèn)題

    今天小編就為大家分享一篇解決element UI 自定義傳參的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • 關(guān)于vue-router路徑計(jì)算問(wèn)題

    關(guān)于vue-router路徑計(jì)算問(wèn)題

    這篇文章主要介紹了關(guān)于vue-router路徑計(jì)算問(wèn)題,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • vue中移動(dòng)端調(diào)取本地的復(fù)制的文本方式

    vue中移動(dòng)端調(diào)取本地的復(fù)制的文本方式

    這篇文章主要介紹了vue中移動(dòng)端調(diào)取本地的復(fù)制的文本方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-07-07
  • Vue中SSR的作用是什么

    Vue中SSR的作用是什么

    這篇文章主要介紹了Vue中SSR的作用及使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • 基于vue實(shí)現(xiàn)動(dòng)態(tài)Tab標(biāo)簽頁(yè)功能

    基于vue實(shí)現(xiàn)動(dòng)態(tài)Tab標(biāo)簽頁(yè)功能

    這篇文章主要介紹了如何基于vue實(shí)現(xiàn)動(dòng)態(tài)Tab標(biāo)簽頁(yè)功能,文中通過(guò)代碼示例和圖文結(jié)合的方式給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-09-09
  • Vue2+JS實(shí)現(xiàn)掃雷小游戲

    Vue2+JS實(shí)現(xiàn)掃雷小游戲

    實(shí)現(xiàn)小游戲可以鍛煉自己的邏輯思維能力,也不會(huì)很枯燥,完成時(shí)會(huì)給自己帶來(lái)一種滿(mǎn)足感。本文就將利用Vue和JS實(shí)現(xiàn)簡(jiǎn)單的掃雷小游戲,需要的可以參考一下
    2022-06-06
  • Vue加載組件、動(dòng)態(tài)加載組件的幾種方式

    Vue加載組件、動(dòng)態(tài)加載組件的幾種方式

    組件是Vue.js最強(qiáng)大的功能之一。組件可以擴(kuò)展HTML元素,封裝可重用的代碼。這篇文章通過(guò)實(shí)例代碼給大家介紹了Vue加載組件、動(dòng)態(tài)加載組件的幾種方式,需要的朋友參考下吧
    2018-08-08

最新評(píng)論

平陆县| 灵山县| 上饶市| 蒲城县| 尚义县| 辽源市| 定日县| 尼木县| 陆河县| 陆丰市| 保定市| 芒康县| 闽侯县| 麟游县| 蒙阴县| 多伦县| 长泰县| 中牟县| 禄劝| 缙云县| 永寿县| 惠安县| 祁阳县| 阜平县| 宝坻区| 郯城县| 泾源县| 阿拉善右旗| 三门峡市| 玉门市| 安图县| 营山县| 曲阜市| 陕西省| 福建省| 云安县| 赤水市| 双鸭山市| 客服| 准格尔旗| 宜兰县|