wanggang
1 year ago
6 changed files with 215 additions and 6 deletions
@ -0,0 +1,171 @@ |
|||
import html from "html"; |
|||
import { ref, nextTick } from "vue"; |
|||
import { useRoute, onBeforeRouteUpdate, useRouter } from "vue-router"; |
|||
import Icon from "../components/icon/index.js"; |
|||
import { useAppStore } from "../store/index.js"; |
|||
import MenuItem from "./menu-item.js"; |
|||
|
|||
export default { |
|||
components: { Icon, MenuItem }, |
|||
template: html`<el-tabs
|
|||
v-model="model" |
|||
type="border-card" |
|||
class="router-tab" |
|||
@tab-remove="remove" |
|||
@tab-click="onClick" |
|||
> |
|||
<template v-for="(item, index) in appStore.routes" :key="item.fullPath"> |
|||
<el-tab-pane v-model="item.fullPath" :name="item.fullPath" :closable="appStore.routes.length > 1"> |
|||
<template #label> |
|||
<el-dropdown |
|||
:ref="(el) => setRef(index, el)" |
|||
class="h-full" |
|||
trigger="contextmenu" |
|||
@visible-change="showContextMenu(index, $event)" |
|||
> |
|||
<span class="inline-flex items-center"> |
|||
<el-icon><icon v-if="item.meta.icon" :name="item.meta.icon" /></el-icon> |
|||
{{ item.meta?.title ?? item.fullPath }} |
|||
</span> |
|||
<template #dropdown> |
|||
<el-dropdown-menu> |
|||
<el-dropdown-item @click="refresh(index)"><i-ep-refresh />刷新</el-dropdown-item> |
|||
<el-dropdown-item :disabled="index === 0" @click="removeLeft(index)"> |
|||
<i-ep-back />关闭左侧 |
|||
</el-dropdown-item> |
|||
<el-dropdown-item :disabled="index === appStore.routes.length - 1" @click="removeRight(index)"> |
|||
<i-ep-right />关闭右侧 |
|||
</el-dropdown-item> |
|||
<el-dropdown-item |
|||
:disabled="index === 0 && index === appStore.routes.length - 1" |
|||
@click="removeOthers(index)" |
|||
> |
|||
<i-ep-switch />关闭其他 |
|||
</el-dropdown-item> |
|||
</el-dropdown-menu> |
|||
</template> |
|||
</el-dropdown> |
|||
</template> |
|||
</el-tab-pane> |
|||
</template> |
|||
</el-tabs>`, |
|||
styles: html` |
|||
<style> |
|||
.router-tab { |
|||
box-sizing: border-box; |
|||
height: 40px !important; |
|||
background-color: var(--el-fill-color-blank); |
|||
border-width: 0 !important; |
|||
} |
|||
|
|||
.router-tab .el-tabs__item { |
|||
padding: 13px !important; |
|||
border-bottom-width: 0; |
|||
} |
|||
|
|||
.router-tab .el-tabs__content { |
|||
display: none; |
|||
} |
|||
</style> |
|||
`,
|
|||
setup() { |
|||
const appStore = useAppStore(); |
|||
const itemRefs = ref([]); |
|||
const currentRoute = useRoute(); |
|||
const router = useRouter(); |
|||
const model = ref(currentRoute.fullPath); |
|||
|
|||
onBeforeRouteUpdate((to) => { |
|||
model.value = to.fullPath; |
|||
}); |
|||
|
|||
const setRef = (index, el) => { |
|||
if (el) { |
|||
itemRefs.value[index] = el; |
|||
} else { |
|||
itemRefs.value.splice(index, 1); |
|||
} |
|||
}; |
|||
const showContextMenu = (index, show) => { |
|||
if (show) { |
|||
itemRefs.value.forEach((item, i) => { |
|||
if (i !== index) { |
|||
item?.handleClose(); |
|||
} |
|||
}); |
|||
} |
|||
}; |
|||
|
|||
const refresh = (index) => { |
|||
const currentIndex = appStore.routes.findIndex((o) => o.fullPath === currentRoute.fullPath); |
|||
const route = appStore.routes[index]; |
|||
if (index !== currentIndex) { |
|||
router.push({ path: route.fullPath }); |
|||
} |
|||
appStore.isRefreshing = true; |
|||
nextTick(() => { |
|||
appStore.isRefreshing = false; |
|||
}); |
|||
}; |
|||
|
|||
const remove = (name) => { |
|||
if (appStore.routes.length > 1) { |
|||
const index = appStore.routes.findIndex((o) => o.fullPath === name); |
|||
const currentIndex = appStore.routes.findIndex((o) => o.fullPath === currentRoute.fullPath); |
|||
appStore.routes.splice(index, 1); |
|||
if (index === currentIndex) { |
|||
if (appStore.routes[index]) { |
|||
router.push(appStore.routes[index]); |
|||
} else { |
|||
router.push(appStore.routes[index - 1]); |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
|
|||
const removeLeft = (index) => { |
|||
const currentIndex = appStore.routes.findIndex((o) => o.fullPath === currentRoute.fullPath); |
|||
const route = appStore.routes[index]; |
|||
appStore.routes.splice(0, index); |
|||
if (currentIndex < index) { |
|||
router.push(route); |
|||
} |
|||
}; |
|||
|
|||
const removeRight = (index) => { |
|||
const currentIndex = appStore.routes.findIndex((o) => o.fullPath === currentRoute.fullPath); |
|||
appStore.routes.splice(index + 1, appStore.routes.length - index); |
|||
if (currentIndex > index) { |
|||
router.push(appStore.routes[index]); |
|||
} |
|||
}; |
|||
|
|||
const removeOthers = (index) => { |
|||
removeRight(index); |
|||
removeLeft(index); |
|||
if (appStore.routes[0].fullPath !== currentRoute.fullPath) { |
|||
router.push(appStore.routes[0]); |
|||
} |
|||
}; |
|||
|
|||
const onClick = (context) => { |
|||
if (!context.active) { |
|||
router.push(context.props.name); |
|||
} |
|||
}; |
|||
return { |
|||
model, |
|||
appStore, |
|||
itemRefs, |
|||
onBeforeRouteUpdate, |
|||
setRef, |
|||
showContextMenu, |
|||
refresh, |
|||
remove, |
|||
removeLeft, |
|||
removeRight, |
|||
removeOthers, |
|||
onClick, |
|||
}; |
|||
}, |
|||
}; |
Loading…
Reference in new issue