开启掘金成长之旅!这是我参与「掘金日新计划 · 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项目中编写后台页面的标签页栏的全部代码和说明