vue3的tabs选项卡的制作
tabs选项卡
·
思路
- 点击左侧菜单,右侧内容展示区显示对应的选项卡
- 点击右侧选项卡,左侧菜单也相应的选中。点击tabs跳转到相应的路径,route.push,菜单中用computed监听path的变化
- 解决刷新后,tabs数据丢失的问题
因为route可以直接获取到当前路由的path等信息,不用在菜单中点击菜单的触发方法,直接获取当前的路由,然后菜单页面和tabs页面都用computed监听path的变化
tabs选项卡存储在store里面
因为菜单组件和tab标签页组建共享tabs数组,所以存储在store里面
首先创建tabs标签的接口:
// 选项卡的数据类型, 规定数据类型就只能有title 和 path
export interface ITabe{
title:string,
path:string
}
在store里面
export interface State {
count: number,
collapse: boolean,
tabsList: Array<ITabe>
}
export const key: InjectionKey<Store<State>> = Symbol()
export const store = createStore<State>({
state: {
tabsList: []
},
mutations: {
addTabe(state: State, tab: ITabe) {
// 判断是否已经存在,如果不存在,才放入
if(state.tabsList.some(item => item.path === tab.path)) return;
state.tabsList.push(tab)
}
},
getters: {
// 获取Tabs
getTabs(state: State) {
return state.tabsList
}
}
})
tabs页面
获取tabs数据
const tabsList = computed(() => {
return store.getters['getTabs']
})
添加选项卡(每点击菜单,就添加一个)
const addTab = () => {
const { path, meta } = route
const tab: ITabe = {
path: path,
title: meta.title as string
}
store.commit('addTabe', tab)
}
点击选项卡
const clickBtn = (tab: any) => {
const { props } = tab
//跳转路由
router.push({ path: props.name })
}
当前激活的选项卡(当前所在的路由)
const activeTab = ref('2') //是v-model的绑定
const setActiveTab = () => {
activeTab.value = route.path
}
删除选项卡
//删除选项卡,跳转到临近页面,这个tabs标签删除
const removeTab = (targetName: string) => {
if(store.state.tabsList.length === 1) return
const tabs = tabsList.value
let activeName = activeTab.value
if (activeName === targetName) { //如果当前的路由是要删除的页面
tabs.forEach((tab:ITabe, index:number) => {
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:ITabe) => tab.path !== targetName)
//跳转路由
router.push({path: activeName})
}
解决刷新数据丢失的问题
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
}
}
}
完整代码
<template>
<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>
</template>
<script lang="ts" setup>
import { onMounted, ref,watch,computed } from 'vue'
import { useStore } from '@/store';
import { useRoute, useRouter } from 'vue-router';
import { ITabe } from '@/store/type';
const store = useStore()
const route = useRoute()
const router = useRouter()
//获取tabs数据
const tabsList = computed(() => {
return store.getters['getTabs']
})
console.log(tabsList,"tabsList")
// let tabIndex = 2
const activeTab = ref('2')
//点击选项卡,跳转到相应的页面,菜单也恢复到相应的页面
const clickBtn = (tab:any) => {
const { props } = tab
router.push({path: props.name})
}
//删除选项卡,跳转到临近页面,这个tabs标签删除
const removeTab = (targetName: string) => {
if(store.state.tabsList.length === 1) return
const tabs = tabsList.value
let activeName = activeTab.value
if (activeName === targetName) { //如果当前的路由是要删除的页面
tabs.forEach((tab:ITabe, index:number) => {
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:ITabe) => tab.path !== targetName)
//跳转路由
router.push({path: activeName})
}
//添加路由的选项卡
const addTabs = () => {
const { path,meta } = route
const tabs:ITabe = {
title: meta.title as string,
path: path
}
store.commit('addTab',tabs)
}
//激活选项卡
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()
})
</script>
<style>
</style>
更多推荐
已为社区贡献2条内容
所有评论(0)