- router请移步下面链接
vue3整合routerhttps://blog.csdn.net/z3133464733/article/details/130019573
- 创建ts文件配置store
由于不会分模块目前只用了一个store......
- 安装vuex4
npm install vue-router@4
- 定义store/index.ts
import { createStore, Store, useStore as baseUserStore } from 'vuex'
import { InjectionKey } from 'vue'
// 为 store state 声明类型
export interface State {
active: string
isCollapse: boolean
token: string
name: string
tabs: []
}
// 定义 injection key
export const key: InjectionKey<Store<State>> = Symbol()
// 创建一个新的 store 实例
export const store = createStore<State>({
state: {
active: sessionStorage.getItem('active' || '') + '',
isCollapse: false,
token: sessionStorage.getItem('token' || '') + '',
name: sessionStorage.getItem('name' || '') + '',
tabs: []
},
mutations: {
SET_COLLAPSE(state: State, isCollapse: boolean) {
state.isCollapse = isCollapse
sessionStorage.setItem('isCollapse', isCollapse + '')
},
SET_ACTIVE(state: State, active: string) {
state.active = active
sessionStorage.setItem('active', active)
},
SET_TOKEN(state: State, token: string) {
state.token = token
sessionStorage.setItem('token', token)
},
SET_NAME(state: State, name: string) {
state.name = name
sessionStorage.setItem('name', name)
},
SET_TABS(state: State, tabs: []) {
state.tabs = tabs
sessionStorage.setItem('tabs', JSON.stringify(tabs))
}
},
getters: {
active(state: State) {
return state.active
},
name(state: State) {
return state.name
},
token(state: State) {
return state.token
},
isCollapse(state: State) {
return state.isCollapse
},
tabs(state: State) {
return state.tabs
}
}
})
export function useStore() {
return baseUserStore(key)
}
- 使用store
<template>
<el-tabs v-model="activeTab" @tab-click="clickTab" type="border-card" class="demo-tabs" closable @edit="removeTab">
<el-tab-pane v-for="item in tabs" :key="item.path" :label="item.name" :name="item.path">
</el-tab-pane>
<!--路由占位符-->
<router-view></router-view>
</el-tabs>
</template>
<script lang="ts" setup true>
import { useStore } from '@/store';
import { useRoute,useRouter } from 'vue-router';
import { computed, onMounted, reactive, ref, watch } from 'vue';
const router = useRouter();
const route = useRoute();
const store = useStore();
const tabs = computed(() => {
if (store.getters.tabs.length == 0) {
const welcome = reactive({ path: "/welcome", name: "欢迎界面" })
store.commit('SET_TABS', [welcome])
}
return store.getters.tabs
})
const activeTab = ref('/welcome')
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
console.info(tablist.filter((tab: any) => tab.path !== targetName))
store.commit('SET_TABS', tablist.filter((tab: any) => tab.path !== targetName))
router.push({ path: activeName })
}
const clickTab = (tab: any) => {
const { props } = tab
router.push({ path: props.name })
}
const addTab = () => {
const { path, name } = route
const newTb = {
path,
name
}
let oldTabs: any = []
tabs.value.forEach((element: any) => {
oldTabs.push(element.path)
});
if (!oldTabs.includes(path)) {
tabs.value.push(newTb)
}
}
watch(() => route.path, () => {
setActive();
addTab();
})
const beforeRefresh = () => {
window.addEventListener('beforeunload', () => {
sessionStorage.setItem("tabsView", JSON.stringify(store.getters.tabs))
})
let tabSession = sessionStorage.getItem("tabsView")
if (tabSession) {
let oldTabs = JSON.parse(tabSession);
if (oldTabs.length > 0) {
store.commit('SET_TABS', oldTabs)
}
}
}
onMounted(() => {
beforeRefresh();
setActive();
})
</script>
<style scoped lang="scss">
.demo-tabs {
min-height: 100vh;
border: none;
border-radius: 5px;
--el-tabs-header-height:40px;
}
</style>