vite+vue项目之后台页面的标签页栏代码编写

200 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第15天,点击查看活动详情


写在前面

上篇文章介绍了如何在vite+vue项目中编写后台页面的侧边菜单栏代码,本篇文章介绍如何在vite+vue项目中编写后台页面的标签页栏代码

完整源码:项目gitee地址

在线演示:演示地址

账号:admin
密码:admin

标签页栏代码及说明

首先,在store文件夹下的index.ts文件中添加如下代码:

import { tabsStore } from './modules/tabs'
...
export const registerStore = () => {
	store.tabsStore = tabsStore()
}

然后在modules文件夹下新增一个tabs.ts文件,在里面编写关闭单个标签(先将点击关闭的标签关闭,然后将页面跳转至下一个标签,若是没有,则跳转至上一个标签,要是都没有,就跳转至主页面)、关闭所有标签(关闭多有标签后跳转至主页面)、关闭其他标签(关闭除当前页面的其他标签)、点击标签/页面(添加当前点击的标签,并跳转至点击的标签的页面)的代码,一开始存在导航页的tab:

import { defineStore } from 'pinia'
import { router } from '@/router/index'

export const tabsStore = defineStore('tabsStore', {
	state: () => ({
		tabList: [{
			title: '导航页',
			path: "/Dashboard",
			name: 'Dashboard',
		}] as any[],
	}),
	actions: {
		// 关闭单个标签
		closeTab(tabIndex: any, curRoute: any) {
			const delItem = this.tabList.splice(tabIndex, 1)[0];
			const item = this.tabList[tabIndex]
				? this.tabList[tabIndex]
				: this.tabList[tabIndex - 1];
			if (item) {
				console.log('item', item)
				console.log('delItem.name', delItem.name)
				console.log('curRoute.name', curRoute.name)
				if (delItem.name === curRoute.name) {
					router.push(item.path)
				}
			} else {
				router.push("/");
			}
		},
		// 关闭所有标签
		closeAllTabs() {
			this.tabList = [{
				title: '导航页',
				path: "/Dashboard",
				name: 'Dashboard',
			}]
			router.push("/");
		},
		// 关闭其他标签
		closeOtherTab(curRoute: any) {
			const curItem = this.tabList.filter((item) => item.path === curRoute.fullPath);
			this.tabList = curItem;
		},
		// 添加标签
		addTab(route: any) {
			const isExist = this.tabList.some((item) => item.path === route.fullPath);
			if (!isExist) {
				this.tabList.push({
					title: route.meta.title,
					path: route.fullPath,
					name: route.name,
				});
			}
		}
	}
})

然后在layout文件夹下的Tabs.vue文件中编写如下代码,包含以下功能:关闭单个标签,关闭其他标签,关闭所有标签(后跳转至Dashboard页面),选中某个标签。

<template>
  <el-tabs v-model="activeName" type="card" closable @tab-remove="removeTab" @tab-click="handleClickTab">
    <el-tab-pane v-for="item in tabList" :key="item.name" :label="item.title" :name="item.name">
    </el-tab-pane>
  </el-tabs>
  <el-dropdown class="tag_handle" @command="handleCommand">
    <el-button type="primary">
      标签操作<el-icon class="el-icon--right"><arrow-down /></el-icon>
    </el-button>
    <template #dropdown>
      <el-dropdown-menu>
        <el-dropdown-item command="closeAllTag">关闭所有标签</el-dropdown-item>
        <el-dropdown-item command="closeOtherTag">关闭其他标签</el-dropdown-item>
      </el-dropdown-menu>
    </template>
  </el-dropdown>
</template>

<script setup lang="ts">
import { ArrowDown } from '@element-plus/icons-vue'
import { watch, onMounted, ref } from 'vue'
import store from "@/store";
import { computed } from '@vue/reactivity';
import { useRoute, useRouter } from "vue-router";

const route = useRoute()
const router = useRouter()

let activeName = ref(route.name)
const tabList = computed(() => store.tabsStore.tabList)

watch(route, (newValue) => {
  if (newValue.name) {
    activeName.value = newValue.name
    addTab(newValue)
  }
})

onMounted(() => {
  addTab(route)
})

// 标签被选中
const handleClickTab = (tab: any) => router.push({ name: tab.props.name || '' })

// 添加标签
const addTab = (route: any) => store.tabsStore.addTab(route)

// 移除标签
const removeTab = (targetName: String) => {
  const curIndex = store.tabsStore.tabList.findIndex((el: any) => el.name == targetName);
  store.tabsStore.closeTab(curIndex, route);
}

// 下拉事件
const handleCommand = (command: string) => {
  switch (command) {
    case 'closeAllTag':
      store.tabsStore.closeAllTabs()
      break
    case 'closeOtherTag':
      store.tabsStore.closeOtherTab(route)
      break
  }
}
</script>

<style lang="less" scoped>
:deep(.el-tabs__header) {
  margin: 0 140px 0 0;
}

:deep(.el-tabs__item.is-active) {
  background: #fff;
}

.tag_handle {
  position: absolute;
  top: 3px;
  right: 8px;
}
</style>

写在最后

以上就是在在vite+vue项目中编写后台页面的标签页栏的全部代码和说明