使用vue3.2實(shí)現(xiàn)多頁(yè)簽導(dǎo)航
一、實(shí)現(xiàn)思路
- 單擊菜單時(shí)數(shù)據(jù)添加store對(duì)象,添加數(shù)據(jù)時(shí)要去重以及數(shù)量限制,不可無(wú)限添加
- 多頁(yè)簽導(dǎo)航數(shù)據(jù)從store對(duì)象里取
- 初始化會(huì)顯示【首頁(yè)】標(biāo)簽導(dǎo)航,同時(shí)固定不可刪除
- 單擊多頁(yè)簽導(dǎo)航,跳轉(zhuǎn)到對(duì)應(yīng)路由
- 激活樣式處理
- 持久化處理
- 刪除多頁(yè)簽導(dǎo)航事件
二、具體實(shí)現(xiàn)步驟
1. 定義store
// src/store/tag-list.js
import { defineStore } from "pinia";
export const useTagStore = defineStore('tag',{
state: ()=> ({
tagList: [
// 初始化默認(rèn)展示【首頁(yè)】標(biāo)簽導(dǎo)航
{
path:'/index',
name: 'index',
meta: { title: '首頁(yè)'}
}
]
}),
getters: {
tagListGetter: state=> state.tagList
},
actions: {
addTag(item) {
this.tagList.push(item)
},
delTag(item) {
// 找出要?jiǎng)h除的tag的索引值
const i = this.tagList.findIndex(v => v.path === item.path)
this.tagList.splice(i,1)
}
},
// 持久化
persist: {
enabled: true, // 開(kāi)啟
strategies: [
{
key: 'tagList',
storage: sessionStorage
}
]
}
2. 單擊菜單時(shí)數(shù)據(jù)添加store對(duì)象
在導(dǎo)航組件中(naveItem.vue)添加點(diǎn)擊事件addTag
<!-- 無(wú)子級(jí) -->
<el-menu-item :index="item.path" v-if="!item.children" @click="addTag(item)">
<el-icon><Menu /></el-icon>
<span>{{item.meta.title}}</span>
</el-menu-item>
<!-- 有子級(jí) -->
<el-sub-menu :index="item.path" v-else>
<template #title>{{item.meta.title}}</template>
<nav-item v-for="sub in item.children" :key="sub.path" :item="sub"></nav-item>
</el-sub-menu>
addTag方法邏輯如下,已有注釋,不再詳細(xì)說(shuō)明。
import { storeToRefs } from 'pinia'
import { useTagStore } from '@/store/tag-list.js'
const tagStore = useTagStore()
const { tagList } = storeToRefs(tagStore)
const { item } = defineProps({
item: {
type: Object
}
})
// 點(diǎn)擊路由,添加標(biāo)簽導(dǎo)航,注意去重
const addTag = (item) => {
// 添加前判斷是否已存在
const isRepeat = tagList.value.some(v => v.path === item.path) // 找到則返回true,否則返回false
if(isRepeat) return
// 限制最多只能打開(kāi)10個(gè)標(biāo)簽導(dǎo)航頁(yè)
if(tagList.value.length === 10) {
// 自動(dòng)把第二個(gè)刪除
tagStore.delTag(tagList.value[1])
}
// 添加
tagStore.addTag(item)
}
3. 定義一個(gè)tag組件
定義一個(gè)tag組件,從store中取出tagList并渲染;
1.首頁(yè)標(biāo)簽導(dǎo)航不可關(guān)閉,通過(guò)當(dāng)前tag的path不等于首頁(yè)的path來(lái)控制el-tag的closeable是否展示;
2.定義默認(rèn)展示的導(dǎo)航標(biāo)簽defaultUrl,默認(rèn)為首頁(yè)的path(/index);通過(guò)監(jiān)聽(tīng)路由變化,將defaultUrl 等于變化后的路由地址;并且在template中判斷:tag的path是否等于defaultUrl,是則不設(shè)置type(el-tag不設(shè)置type默認(rèn)為藍(lán)色),其他則為type=info;
3.點(diǎn)擊導(dǎo)航標(biāo)簽,能夠跳轉(zhuǎn)到對(duì)應(yīng)路由,給標(biāo)簽添加handleJump事件。
4.刪除導(dǎo)航標(biāo)簽事件
a.刪除的不是當(dāng)前激活模塊,正常刪除
b.刪除的是當(dāng)前激活模塊
- 當(dāng)前激活模塊是最后一個(gè)導(dǎo)航標(biāo)簽,則需要高亮前一個(gè)導(dǎo)航標(biāo)簽
- 當(dāng)前激活模塊不是最后一個(gè)導(dǎo)航標(biāo)簽,則需要高亮后一個(gè)導(dǎo)航標(biāo)簽
代碼代碼如下:
<div class="tags">
<el-scrollbar class="scroll-container">
<el-tag
v-for="(tag,index) in tagList"
:key="tag.path"
class="mx-1"
:closable="tag.path !== '/index'"
:type="tag.path === defaultUrl? '' : 'info'"
@click="handleJump(tag)"
@close="handleClose(tag,index)"
>
{{ tag?.meta?.title }}
</el-tag>
</el-scrollbar>
</div>
import { ref,watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { storeToRefs } from 'pinia'
import { useTagStore } from '@/store/tag-list.js'
const route = useRoute()
const router = useRouter()
const tagStore = useTagStore()
const { tagList } = storeToRefs(tagStore)
// 高亮當(dāng)前路由導(dǎo)航的標(biāo)簽頁(yè)
const defaultUrl = ref('/idnex')
watch(route,(newVal,oldVal) => {
defaultUrl.value = newVal.path
},{deep: true,immediate: true})
// 跳轉(zhuǎn)路由
const handleJump = (tag) => {
// 重復(fù)點(diǎn)擊標(biāo)簽,不跳轉(zhuǎn)
if(route.path === tag.path) return
router.push(tag.path)
}
// 關(guān)閉標(biāo)簽
const handleClose = (tag, i) => {
// store 刪除
tagStore.delTag(tag)
// 1.刪除非當(dāng)前模塊,正常刪除
if(route.path !== tag.path) return
// 2.刪除當(dāng)前模塊
if(i === tagList.value.length) {
// 2.1當(dāng)前模塊屬于最后一個(gè)模塊,刪除后需要高亮前一個(gè)模塊
handleJump(tagList.value[i-1])
}else {
// 2.2當(dāng)前模塊屬于中間模塊模塊,刪除后需要高亮后一個(gè)模塊
handleJump(tagList.value[i])
}
}
具體效果

到此這篇關(guān)于使用vue3.2實(shí)現(xiàn)多頁(yè)簽導(dǎo)航的文章就介紹到這了,更多相關(guān)vue多頁(yè)簽導(dǎo)航內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決@vue/cli安裝成功后,運(yùn)行vue -V報(bào):不是內(nèi)部或外部命令的問(wèn)題
這篇文章主要介紹了解決@vue/cli安裝成功后,運(yùn)行vue -V報(bào):不是內(nèi)部或外部命令的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
vue常見(jiàn)路由跳轉(zhuǎn)的幾種方式小結(jié)
本文主要介紹了常見(jiàn)路由跳轉(zhuǎn)的幾種方式,主要介紹了四種常見(jiàn)方式,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09
解決elementui中NavMenu導(dǎo)航菜單高亮問(wèn)題(解決多種情況)
這篇文章主要介紹了解決elementui中NavMenu?導(dǎo)航菜單高亮問(wèn)題(解決多種情況),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05
vue3中的數(shù)據(jù)劫持的最新實(shí)現(xiàn)方案的proxy示例詳解
Vue3中使用Proxy實(shí)現(xiàn)數(shù)據(jù)劫持,解決了Vue2中數(shù)組和對(duì)象劫持的遺留問(wèn)題,Proxy可以修改某些操作的默認(rèn)行為,通過(guò)get和set方法實(shí)現(xiàn)數(shù)據(jù)的劫持和保護(hù)機(jī)制,感興趣的朋友跟隨小編一起看看吧2024-11-11
vue 實(shí)現(xiàn)基礎(chǔ)組件的自動(dòng)化全局注冊(cè)
這篇文章主要介紹了vue 實(shí)現(xiàn)基礎(chǔ)組件的自動(dòng)化全局注冊(cè)的方法,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下2020-12-12
Vue3中實(shí)現(xiàn)歌詞滾動(dòng)顯示效果
本文分享如何在Vue 3中實(shí)現(xiàn)一個(gè)簡(jiǎn)單的歌詞滾動(dòng)效果,我將從歌詞數(shù)據(jù)的處理開(kāi)始,一步步介紹布局的搭建和事件的實(shí)現(xiàn),感興趣的朋友跟隨小編一起看看吧2024-02-02
Vue利用廣度優(yōu)先搜索實(shí)現(xiàn)watch
這篇文章主要為大家學(xué)習(xí)介紹了Vue如何利用廣度優(yōu)先搜索實(shí)現(xiàn)watch(有意思),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-08-08

