Vue3 + Element Plus 实现动态标签页及右键菜单

目录

先上图

 使用el-dropdown绑定右键菜单,为每个tab页绑定一个右键

右键菜单生效后控制每个下拉项的禁用与显示(每一项代表一个功能)

每个右键项对应的功能 

控制每次只显示一个右键

完整代码


先上图

        只有首页的情况

Vue3 + Element Plus 实现动态标签页及右键菜单

        多个tab页的情况

Vue3 + Element Plus 实现动态标签页及右键菜单

 使用el-dropdown绑定右键菜单,为每个tab页绑定一个右键

        
            
                
                    {{ item.name }}
                    
                        
                            
                                
                                    
                                重新刷新
                            
                            
                                
                                    
                                关闭当前
                             1" @click="closeOther(item)"
                                :disabled="handDisabled('closeOther', item, index)">
                                
                                    
                                关闭其他
                             1" @click="closeAll(item)"
                                :disabled="handDisabled('closeAll', item, index)">
                                
                                    
                                关闭全部
                        
                    
                
            
        
        
        
    

右键菜单生效后控制每个下拉项的禁用与显示(每一项代表一个功能)

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()
    })
}

完整代码

    
        
            
                
                    {{ item.name }}
                    
                        
                            
                                
                                    
                                重新刷新
                            
                            
                                
                                    
                                关闭当前
                             1" @click="closeOther(item)"
                                :disabled="handDisabled('closeOther', item, index)">
                                
                                    
                                关闭其他
                             1" @click="closeAll(item)"
                                :disabled="handDisabled('closeAll', item, index)">
                                
                                    
                                关闭全部
                        
                    
                
            
        
        
        
    



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刷新数据丢失
// 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();
})




.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;
}

 

本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/39bfbda248.html