点击菜单生成tabs(vue3.0)

1.安装vuex

 npm install vuex@next --save

在main.js中引用vuex

2.在main.js同级目录新建store/store.js文件

 代码:

import { createStore } from 'vuex'
export default createStore({
	state: {
		tabsList: []
	},
	mutations: {
		addTab(state, tab) {
			// 判断是否已经存在,如果不存在,才放入
			if(state.tabsList.some(item => item.path === tab.path)) return;
			state.tabsList.push(tab)
		}
	},
	getters: {
		// 获取Tabs
		getTabs(state) {
			return state.tabsList
		}
	}
})

  

  

3.在admin.vue页实现功能

 html代码:

<el-tabs v-model="activeTab" @tab-click="clickBtn" type="card" class="demo-tabs" closable @tab-remove="removeTab">
		<el-tab-pane v-for="item in tabsList" :key="item.path" :label="item.title" :name="item.path">
		</el-tab-pane>
</el-tabs>

  

js代码:

<script setup>
    import { useStore } from 'vuex'
    import { useRoute, useRouter } from 'vue-router';
    import { reactive, onMounted, computed, watch, ref } from 'vue';
    let isCollapse = ref(false)
    /*选项卡*/
    const store = useStore()
    const route = useRoute()
    const router = useRouter()
    const tabsList = computed(() => {
        return store.getters['getTabs']
    })
    //console.log(tabsList, "tabsList")
    const activeTab = ref('2')

    //点击选项卡,跳转到相应的页面,菜单也恢复到相应的页面
    const clickBtn = (tab) => {
        const {
            props
        } = tab
        router.push({
            path: props.name
        })
    }

    //删除选项卡,跳转到临近页面,这个tabs标签删除
    const removeTab = (targetName) => {
        if(store.state.tabsList.length === 1) return
        const tabs = tabsList.value
        let activeName = activeTab.value
        if(activeName === targetName) { //如果当前的路由是要删除的页面
            tabs.forEach((tab, index) => {
                if(tab.path === targetName) {
                    const nextTab = tabs[index + 1] || tabs[index - 1] //如果在中间的tab,删除会选择在后面的一个;如果在最后,会选择在前面的一个tab
                    if(nextTab) {
                        activeName = nextTab.path //更换当前路由的地址
                    }
                }
            })
        }
        //重新设置当前激活的选项卡
        activeTab.value = activeName
        //重新设置选项卡数据,将数组中去掉删除的元素
        store.state.tabsList = tabs.filter((tab) => tab.path !== targetName)
        //跳转路由
        router.push({
            path: activeName
        })
    }

    //添加路由的选项卡
    const addTabs = () => {
        const {
            path,
            meta,
            name
        } = route
        const tabs = {
            title: name,
            path: path
        }
        store.commit('addTab', tabs)
        //store.state.tabsList=[]
    }
    //激活选项卡
    const setActiveTab = () => {
        activeTab.value = route.path //因为el-tab-pane的name是item.path,所以activeTab也是path
    }

    watch(() => route.path, () => {
        //激活选项卡
        setActiveTab()
        //监听路由的变化
        addTabs()
    })

    //解决刷新数据页面丢失的问题
    const beforeRefresh = () => {
        window.addEventListener("beforeunload", () => { //监听刷新
            // sessionStorage当浏览器关闭时,结束。localStorage,没有期限
            sessionStorage.setItem('tabsView', JSON.stringify(tabsList.value))
        })
        //页面加载时取数据
        let tabSession = sessionStorage.getItem('tabsView')
        if(tabSession) {
            let oldTabs = JSON.parse(tabSession)
            if(oldTabs.length > 0) {
                store.state.tabsList = oldTabs
            }
        }
    }
    //调用函数需要在模板加载之后调用
    onMounted(() => {
        beforeRefresh()
        setActiveTab()
        addTabs()
    })
    const toggleCollapse = function() {
        isCollapse.value = !isCollapse.value
    }
</script>

 

 

 

 

 ps参考文档:

https://blog.csdn.net/qq_45489665/article/details/125256001

https://blog.csdn.net/ksx2333/article/details/122292507

posted @ 2024-04-17 15:32  nnc  阅读(59)  评论(0编辑  收藏  举报