wms_vue/src/layout/module/tab/index.vue

172 lines
4.5 KiB
Vue
Raw Normal View History

2025-08-07 15:16:23 +08:00
<template>
<div id="tab" :class="[tabType]">
<a-tabs
hide-add
v-model:activeKey="activeKey"
type="editable-card"
@edit="onEdit"
@change="callback"
class="tab"
>
<a-tab-pane
v-for="pane in panes"
:key="pane.path"
:tab="i18nTitle(pane.i18n)"
:closable="pane.closable"
>
</a-tab-pane>
</a-tabs>
<a-dropdown class="tab-tool" :placement="placement">
<a-button>
<template v-slot:icon>
<DownOutlined />
</template>
</a-button>
<template v-slot:overlay>
<a-menu>
<a-menu-item @click="closeAll()"> </a-menu-item>
<a-menu-item @click="closeOther()"> </a-menu-item>
<a-menu-item @click="closeCurrent()"> </a-menu-item>
</a-menu>
</template>
</a-dropdown>
</div>
</template>
<script>
import _path from "path";
import { computed, reactive, ref, watch } from "vue";
import { useStore } from "vuex";
import { DownOutlined } from "@ant-design/icons-vue";
import { useRouter, useRoute } from "vue-router";
import { useI18n } from "vue-i18n";
import config from '@/configure/pear.config.js';
export default {
components: {
DownOutlined
},
methods: {
callback(key) {
this.selectTab(key);
},
onEdit(targetKey, action) {
this[action](targetKey);
},
closeAll() {
this.closeAllTab();
},
closeOther() {
this.closeOtherTab();
},
closeCurrent() {
this.closeCurrentTab();
},
remove(targetKey) {
this.removeTab(targetKey);
}
},
setup() {
const { getters, commit } = useStore();
const defaultPanes = computed(() => getters.panes);
const initPanes = [];
const panes = ref(initPanes);
const route = useRoute();
const router = useRouter();
const storeKey = computed(() => getters.activeKey);
const activeKey = ref(storeKey.value);
const tabType = computed(() => getters.tabType);
const state = reactive({
menu: computed(() => getters.menu)
});
// store中不允许修改这里转一次
const menu = ref(state.menu);
// 初 始 化 选 项 卡 选 中 项
const findFixedPane = (list, panes) => {
panes.forEach(pane => {
const { path ,meta, hidden, children = [] } = pane;
if (children && children.length > 0) {
findFixedPane(list, children);
} else {
if (!hidden && meta && config.defaultTab === pane.component) {
list.push({
title: meta.title,
path: path,
i18n: meta.i18n,
closable: false
});
}
}
});
};
findFixedPane(initPanes, menu.value);
// 新 增 或 添 加 选 项 卡 操 作
const dynamicMenu = () => {
const title = route.meta.title;
const path = route.path;
const i18n = route.meta.i18n;
commit("app/addTab", { title,path,i18n });
const { fullPath } = route;
const startIndex = fullPath.indexOf("/");
const endIndex = fullPath.lastIndexOf("/");
const openKey = [fullPath.substring(startIndex, endIndex)];
localStorage.setItem("openKey", JSON.stringify(openKey));
};
watch(computed(() => route.fullPath),
dynamicMenu
);
watch(computed(() => getters.panes),
n => (panes.value = n),
{ deep: true, immediate: true }
);
watch(storeKey, targetKey => {
activeKey.value = targetKey;
router.push(targetKey);
});
// 初 始 化 操 作
dynamicMenu(route);
const allTabs = [...initPanes, ...defaultPanes.value];
const tabs = allTabs.reduce((result, current) => {
const resultTitles = result.map(it => it.title);
if (!resultTitles.includes(current.title)) {
return [...result, current];
} else {
return result;
}
}, []);
commit("app/initPanes", tabs);
const { t } = useI18n()
const i18nTitle = function(key) {
if(undefined != key) {
return t(key);
}
return "404";
}
return {
t,
i18nTitle,
placement: ref("bottomRight"),
panes,
activeKey,
tabType,
selectTab: key => commit("app/selectTab", key),
removeTab: key => commit("app/removeTab", key),
closeAllTab: () => commit("app/closeAllTab"),
closeOtherTab: () => commit("app/closeOtherTab"),
closeCurrentTab: () => commit("app/closeCurrentTab")
};
}
};
</script>