Vue3+Element?Plus實現(xiàn)動態(tài)標簽頁以及右鍵菜單功能
更新時間:2023年09月22日 11:42:52 作者:日進斗識
這篇文章主要給大家介紹了關(guān)于Vue3+Element?Plus實現(xiàn)動態(tài)標簽頁以及右鍵菜單功能的相關(guān)資料,Vue?3和Element?Plus提供了一種簡單的方法來實現(xiàn)側(cè)邊菜單欄與標簽頁之間的聯(lián)動,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
先上圖
只有首頁的情況
多個tab頁的情況
使用el-dropdown綁定右鍵菜單,為每個tab頁綁定一個右鍵
<el-tabs v-model="activeTab" @tab-click="clickTab" type="border-card" class="demo-tabs" closable @edit="removeTab"> <el-tab-pane v-for="(item, index) in tabs" :key="item.path" :label="item.name" :name="item.path"> <template #label> <el-dropdown :trigger="['contextmenu']" ref="dropdownRef" :id="item.name" @visible-change="handleChange($event, item.name)"> {{ item.name }} <template #dropdown> <el-dropdown-menu> <el-dropdown-item @click="reload(item)" :disabled="handDisabled('reload', item, index)"> <el-icon> <Refresh /> </el-icon>重新刷新 </el-dropdown-item> <el-dropdown-item v-if="item.path != '/welcome'" @click="closeMy(item)" :disabled="handDisabled('closeMy', item, index)"> <el-icon> <Close /> </el-icon>關(guān)閉當前</el-dropdown-item> <el-dropdown-item v-if="tabs.length > 1" @click="closeOther(item)" :disabled="handDisabled('closeOther', item, index)"> <el-icon> <Remove /> </el-icon>關(guān)閉其他</el-dropdown-item> <el-dropdown-item v-if="tabs.length > 1" @click="closeAll(item)" :disabled="handDisabled('closeAll', item, index)"> <el-icon> <Minus /> </el-icon>關(guān)閉全部</el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> </template> </el-tab-pane> <!--路由占位符--> <router-view></router-view> </el-tabs>
右鍵菜單生效后控制每個下拉項的禁用與顯示(每一項代表一個功能)
const handDisabled = (action: string, data: any, index: any) => { if (action == 'reload') { return route.path != data.path } if (action == 'closeMy') { return route.path != data.path } if (action == 'closeOther') { return route.path != data.path } return false }
每個右鍵項對應的功能
const reload = (item: any) => { router.go(0) } const closeMy = (item: any) => { removeTab(item.path) } const closeOther = (item: any) => { const welcome = { name: "歡迎界面", path: "/welcome" } console.info(item) tabsSt.setTabs([welcome]) const { name, path } = item let oldTabs: any = [] tabs.value.forEach((element: any) => { oldTabs.push(element.path) }); if (!oldTabs.includes(path)) { tabs.value.push({ name: name as any, path }) } } const closeAll = (item: any) => { const welcome = { name: "歡迎界面", path: "/welcome", } tabsSt.setTabs([welcome]) router.push('/welcome') }
控制每次只顯示一個右鍵
const dropdownRef = ref() const handleChange = (visible: boolean, name: string) => { if (!visible) return dropdownRef.value.forEach((item: { id: string; handleClose: () => void }) => { if (item.id === name) return item.handleClose() }) }
完整代碼
<template> <el-tabs v-model="activeTab" @tab-click="clickTab" type="border-card" class="demo-tabs" closable @edit="removeTab"> <el-tab-pane v-for="(item, index) in tabs" :key="item.path" :label="item.name" :name="item.path"> <template #label> <el-dropdown :trigger="['contextmenu']" ref="dropdownRef" :id="item.name" @visible-change="handleChange($event, item.name)"> {{ item.name }} <template #dropdown> <el-dropdown-menu> <el-dropdown-item @click="reload(item)" :disabled="handDisabled('reload', item, index)"> <el-icon> <Refresh /> </el-icon>重新刷新 </el-dropdown-item> <el-dropdown-item v-if="item.path != '/welcome'" @click="closeMy(item)" :disabled="handDisabled('closeMy', item, index)"> <el-icon> <Close /> </el-icon>關(guān)閉當前</el-dropdown-item> <el-dropdown-item v-if="tabs.length > 1" @click="closeOther(item)" :disabled="handDisabled('closeOther', item, index)"> <el-icon> <Remove /> </el-icon>關(guān)閉其他</el-dropdown-item> <el-dropdown-item v-if="tabs.length > 1" @click="closeAll(item)" :disabled="handDisabled('closeAll', item, index)"> <el-icon> <Minus /> </el-icon>關(guān)閉全部</el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> </template> </el-tab-pane> <!--路由占位符--> <router-view></router-view> </el-tabs> </template> <script lang="ts" setup true> import { tabsStore } from '@/pinia/tabs'; import { homeStore } from '@/pinia/home'; import { useRoute, useRouter } from 'vue-router'; import { computed, onMounted, reactive, ref, toRef, watch } from 'vue'; import { Close, Minus, Refresh } from '@element-plus/icons-vue'; const router = useRouter(); const route = useRoute(); const tabsSt = tabsStore(); const { active, menus } = homeStore(); //tabs默認選項卡 const activeTab = ref(active) const tabs = computed(() => { console.info("....初始化tabs") if (tabsSt.getTabs.length == 1) { const welcome = { name: "歡迎界面", path: "/welcome", } tabsSt.setTabs([welcome]) } return tabsSt.getTabs }) //設置tabs選項卡 const setActive = () => { activeTab.value = route.path; } const removeTab = (targetName: any) => { if (targetName === '/welcome') { return } const tablist = tabs.value let activeName = activeTab.value; if (activeName === targetName) { tablist.forEach((tab: any, index: any) => { if (tab.path === targetName) { const nextTab = tablist[index + 1] || tablist[index - 1] if (nextTab) { activeName = nextTab.path } } }) } activeTab.value = activeName tabsSt.setTabs(tablist.filter((tab: any) => tab.path !== targetName)) router.push({ path: activeName }) } const clickTab = (tab: any) => { const { props } = tab router.push({ path: props.name }) } const reload = (item: any) => { router.go(0) } const closeMy = (item: any) => { removeTab(item.path) } const closeOther = (item: any) => { const welcome = { name: "歡迎界面", path: "/welcome" } console.info(item) tabsSt.setTabs([welcome]) const { name, path } = item let oldTabs: any = [] tabs.value.forEach((element: any) => { oldTabs.push(element.path) }); if (!oldTabs.includes(path)) { tabs.value.push({ name: name as any, path }) } } const closeAll = (item: any) => { const welcome = { name: "歡迎界面", path: "/welcome", } tabsSt.setTabs([welcome]) router.push('/welcome') } const dropdownRef = ref() const handleChange = (visible: boolean, name: string) => { if (!visible) return dropdownRef.value.forEach((item: { id: string; handleClose: () => void }) => { if (item.id === name) return item.handleClose() }) } const handDisabled = (action: string, data: any, index: any) => { if (action == 'reload') { return route.path != data.path } if (action == 'closeMy') { return route.path != data.path } if (action == 'closeOther') { return route.path != data.path } return false } const addTab = () => { const { name, path } = route let oldTabs: any = [] tabs.value.forEach((element: any) => { oldTabs.push(element.path) }); if (!oldTabs.includes(path)) { tabs.value.push({ name: name as any, path }) } } watch(() => route.path, () => { setActive(); addTab(); }) //vuex刷新數(shù)據(jù)丟失 // const beforeRefresh = () => { // window.addEventListener('beforeunload', () => { // sessionStorage.setItem("tabsView", JSON.stringify(tabsSt.getTabs)) // }) // let tabSession = sessionStorage.getItem("tabsView") // if (tabSession) { // let oldTabs = JSON.parse(tabSession); // if (oldTabs.length > 0) { // tabsSt.setTabs(oldTabs) // } // } // } const beforeRefresh = () => { window.addEventListener('beforeunload', () => { console.info("beforeunload...") }) } onMounted(() => { beforeRefresh(); setActive(); }) </script> <style lang="scss"> .demo-tabs { // min-height: 100vh; border: none; border-radius: 5px; } .el-tabs--border-card>.el-tabs__content { padding: 10px; } .el-tabs__item { font-size: 8px; font-weight: 1; padding: 0 8px; } </style>
總結(jié)
到此這篇關(guān)于Vue3+Element Plus實現(xiàn)動態(tài)標簽頁以及右鍵菜單功能的文章就介紹到這了,更多相關(guān)Vue3動態(tài)標簽頁及右鍵菜單內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決Vue axios post請求,后臺獲取不到數(shù)據(jù)的問題方法
今天小編就為大家分享一篇解決Vue axios post請求,后臺獲取不到數(shù)據(jù)的問題方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08vue3+ts+vant移動端H5項目搭建的實現(xiàn)步驟
本文主要介紹了vue3+ts+vant移動端H5項目搭建,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-06-06通過GASP讓vue實現(xiàn)動態(tài)效果實例代碼詳解
GASP是一個JavaScript動畫庫,它支持快速開發(fā)高性能的 Web 動畫。GASP 使我們能夠輕松輕松快速的將動畫串在一起,來創(chuàng)造一個高內(nèi)聚的流暢動畫序列。這篇文章主要介紹了通過GASP讓vue實現(xiàn)動態(tài)效果,需要的朋友可以參考下2019-11-11為什么Vue3.0使用Proxy實現(xiàn)數(shù)據(jù)監(jiān)聽(defineProperty表示不背這個鍋)
這篇文章主要介紹了為什么Vue3.0使用Proxy實現(xiàn)數(shù)據(jù)監(jiān)聽?defineProperty表示不背這個鍋,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-10-10