Article directory
foreword
Quick navigation should be familiar to those who are good at front-end development. It can quickly switch to the previously opened page, making the system more flexible and convenient. Here I use the quick navigation implemented by Vue+Element plus+Vuex+Router for your reference.
1. Analysis
Features of quick navigation
- Show opened navigation items
- Click on the navigation item to switch pages
- navigation close
- Navigation close shortcuts (close current, close other, close left, close right and close all)
Tabs
In terms of style, the components and components provided by Element Plus are completely adopted Dropdown
.
Two, realize
- Realize page effects based on
Tabs
components and components provided by Element Plus .Dropdown
code show as below
<template>
<div class="fast-nav">
<el-tabs
v-model="router.currentRoute.value.name"
type="card"
class="tabs"
closable
@tab-click="handleClick"
@contextmenu.prevent.native="openContextMenu($event)"
@tab-remove="removeTab">
<el-tab-pane
v-for="item in tabList"
:key="item.name"
:name="item.name">
<template #label>
<el-space>
<el-icon style="font-size: 18px">
<component class="el-icon" :is="item.menuIcon"></component>
</el-icon>
<span>{
{ store.state.internationalization === 'zhCn' ? item.title : item.titleEn }}</span>
</el-space>
</template>
</el-tab-pane>
</el-tabs>
<el-dropdown ref="dropdown" @command="handleCommand" trigger="contextmenu" style="position: absolute">
<span></span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="a" :icon="CircleClose">{
{ $t('button.closeCurrent') }}</el-dropdown-item>
<el-dropdown-item command="b" :icon="CircleCloseFilled">{
{ $t('button.closeOther') }}</el-dropdown-item>
<el-dropdown-item command="c" :icon="Back">{
{ $t('button.closeLeft') }}</el-dropdown-item>
<el-dropdown-item command="d" :icon="Right">{
{ $t('button.closeRight') }}</el-dropdown-item>
<el-dropdown-item command="e" :icon="DeleteFilled">{
{ $t('button.closeAll') }}</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</template>
- Realize data dynamization
Use Vuex to store the tabList collection, store it in the tabList collection when the route jumps, and delete the corresponding items in the tabList when closing the page to realize dynamization. The specific code is as follows
//路由守卫监听路由变化存储路由信息到tbList中
router.beforeEach(async (to, from, next) => {
store.dispatch("tabList", to).then()
})
//页面获取tabList
import {
useStore} from "@/vuex/store";
const store = useStore();
let tabList = ref(store.state.tabList)
- Realize shortcut-related functions, the specific code is as follows
//关闭指定tab
const removeTab = (targetName: string) => {
//首页不能关闭
if (targetName === tabList.value[0].name) {
return ElMessage.warning('工作台不能关闭 !!!')
}
//获取路由下标
const index = tabList.value.findIndex(item => item.name === router.currentRoute.value.name)
//获取当前选中的tab下标
const current = tabList.value.findIndex(item => item.name === targetName)
//删除当前选中tab
tabList.value.splice(current, 1);
//判断当前下标和路由下标是否相同,是->跳转前一位路由
if (index === current){
router.push(tabList.value[index - 1].name)
}
}
//关闭当前tab
const closeItem = () => {
if (router.currentRoute.value.name === tabList.value[0].name) {
return ElMessage.warning('工作台不能关闭 !!!')
}
//获取路由下标
const index = tabList.value.findIndex(item => item.name === router.currentRoute.value.name)
//获取当前选中的tab下标
tabList.value.splice(index, 1);
//跳转前一位路由
router.push(tabList.value[index - 1].name)
}
//关闭其他tab
const closeOther = () => {
//获取路由下标
const index = tabList.value.findIndex(item => item.name === router.currentRoute.value.name)
//下表是否为0,是->删除0之后的所有数据
if (index === 0) {
tabList.value.splice(1);
}
//下表是否为1且集合长度大于2
if (index === 1 && tabList.value.length > 2) {
tabList.value.splice(2);
}
//下表大于1
if (index > 1) {
tabList.value.splice(1, index - 1);
tabList.value.splice(2);
}
}
//关闭左侧tab
const closeLeft = () => {
//获取路由下标
const index = tabList.value.findIndex(item => item.name === router.currentRoute.value.name)
//判断下表是否大于1
if (index > 1) {
tabList.value.splice(1, index - 1);
}
}
//关闭右侧tab
const closeRight = () => {
//获取路由下标
const index = tabList.value.findIndex(item => item.name === router.currentRoute.value.name)
//判断下表是否小于总长度
if (index < tabList.value.length - 1) {
tabList.value.splice(index + 1, tabList.value.length - index);
}
}
//关闭所有tab
const closeAll = () => {
//判断总长度是否大于1
if (tabList.value.length > 1) {
tabList.value.splice(1);
}
//跳转首页
router.push(tabList.value[0].name)
}
//下拉菜单dom
const dropdown = ref()
//打开下拉菜单并重新定位
const openContextMenu = (e) => {
dropdown.value.handleClose()
setTimeout(() => {
dropdown.value.$el.style.left = e.x + 'px'
dropdown.value.$el.style.top = e.y + 'px'
dropdown.value.handleOpen()
}, 50)
}
const router = useRouter();
//点击tab跳转路由
const handleClick = (tab: TabsPaneContext) => {
router.push(tab.paneName.toString())
}
//点击下拉菜单中的菜单
const handleCommand = (command: string | number | object) => {
switch (command) {
case 'a':
closeItem()
break
case 'b':
closeOther()
break
case 'c':
closeLeft()
break
case 'd':
closeRight()
break
case 'e':
closeAll()
break
}
}
3. Realization effect diagram
Summarize
The fast navigation based on Vue+Element Plus is completed. The main knowledge points involved are Vue3, Vuex, Element Plus and Router. What needs attention is the logic of calculating the following table, and the fast navigation binding Dropdown
components place. If there is a better way to achieve it or if you have any questions, please leave a message in the comment area.
![](https://resource.liulingfengyu.cn/img/扫码_搜索联合传播样式-标准色版压缩版.png)