You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue实现侧边栏点击动态添加标签页(仿AdminLTE)

Vue + Vue Router 实现动态标签页(点击侧边栏添加)

核心逻辑

  1. 用组件内状态或Vuex维护已打开标签页的数组
  2. 拦截侧边栏路由跳转,判断目标路由是否已存在标签页,不存在则动态添加
  3. 支持标签页切换、关闭(保留默认首页)

具体实现代码

主布局组件(Layout.vue)

<template>
  <div class="app-layout">
    <!-- 侧边栏菜单 -->
    <aside class="sidebar">
      <div class="menu-item" v-for="item in menuList" :key="item.path">
        <span @click="handleOpenTab(item)">{{ item.title }}</span>
      </div>
    </aside>

    <!-- 动态标签栏 -->
    <div class="tab-container">
      <div 
        v-for="tab in tabs" 
        :key="tab.path" 
        class="tab-item" 
        :class="{ active: tab.path === $route.path }"
        @click="switchTab(tab.path)"
      >
        {{ tab.title }}
        <span v-if="tab.path !== '/'" class="close-icon" @click.stop="closeTab(tab.path)">×</span>
      </div>
    </div>

    <!-- 路由视图容器 -->
    <div class="content-wrapper">
      <router-view></router-view>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      // 侧边栏菜单配置
      menuList: [
        { path: '/', title: '首页' },
        { path: '/dashboard', title: '仪表盘' },
        { path: '/user-manage', title: '用户管理' },
        { path: '/system-setting', title: '系统设置' }
      ],
      // 已打开标签页,默认加载首页
      tabs: [{ path: '/', title: '首页' }]
    }
  },
  methods: {
    // 点击侧边栏打开/切换标签页
    handleOpenTab(menuItem) {
      const hasTab = this.tabs.some(tab => tab.path === menuItem.path)
      if (!hasTab) {
        this.tabs.push({
          path: menuItem.path,
          title: menuItem.title
        })
      }
      this.$router.push(menuItem.path)
    },
    // 切换标签页路由
    switchTab(path) {
      this.$router.push(path)
    },
    // 关闭指定标签页
    closeTab(path) {
      // 过滤掉要关闭的标签
      this.tabs = this.tabs.filter(tab => tab.path !== path)
      // 若关闭的是当前激活标签,跳转到最后一个标签页
      if (path === this.$route.path) {
        const lastTab = this.tabs[this.tabs.length - 1]
        this.$router.push(lastTab.path)
      }
    }
  },
  // 监听路由变化,处理手动输入URL的场景
  watch: {
    '$route.path'(newPath) {
      const targetMenu = this.menuList.find(item => item.path === newPath)
      if (targetMenu) {
        const hasTab = this.tabs.some(tab => tab.path === newPath)
        if (!hasTab) {
          this.tabs.push({
            path: newPath,
            title: targetMenu.title
          })
        }
      }
    }
  }
}
</script>

<style scoped>
.app-layout {
  display: flex;
  height: 100vh;
}
.sidebar {
  width: 200px;
  background-color: #2c3e50;
  color: #fff;
  padding: 16px 0;
}
.menu-item {
  padding: 12px 24px;
  cursor: pointer;
  transition: background .2s;
}
.menu-item:hover {
  background-color: #34495e;
}
.tab-container {
  display: flex;
  border-bottom: 1px solid #eee;
  background-color: #f8f9fa;
}
.tab-item {
  padding: 10px 18px;
  cursor: pointer;
  border-right: 1px solid #eee;
  position: relative;
}
.tab-item.active {
  background-color: #fff;
  border-top: 2px solid #3498db;
}
.close-icon {
  margin-left: 8px;
  color: #999;
  font-size: 14px;
}
.close-icon:hover {
  color: #e74c3c;
}
.content-wrapper {
  flex: 1;
  padding: 16px;
  overflow-y: auto;
}
</style>

Vue Router 基础配置(router/index.js)

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import Dashboard from '../views/Dashboard.vue'
import UserManage from '../views/UserManage.vue'
import SystemSetting from '../views/SystemSetting.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/dashboard',
    name: 'Dashboard',
    component: Dashboard
  },
  {
    path: '/user-manage',
    name: 'UserManage',
    component: UserManage
  },
  {
    path: '/system-setting',
    name: 'SystemSetting',
    component: SystemSetting
  }
]

const router = new VueRouter({
  mode: 'hash',
  routes
})

export default router

关键注意事项

  • 侧边栏不用直接用router-link,通过点击事件手动触发标签添加和路由跳转,避免默认跳转逻辑冲突
  • 监听路由变化,处理用户手动在地址栏输入URL的情况,确保标签页自动同步
  • 关闭标签页时要判断是否为当前激活标签,防止页面空白

内容的提问来源于stack exchange,提问作者juancho perez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 23:47:36