CodeMaster/node_modules/.cache/vue-loader/626ccf6f5fb492f6ec093c8ed8bccb15.json
2025-04-06 21:59:05 +08:00

1 line
16 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{"remainingRequest":"/Users/shuguang/Desktop/毕设/CodeMaster/CodeMaster/node_modules/vue-loader/lib/index.js??vue-loader-options!/Users/shuguang/Desktop/毕设/CodeMaster/CodeMaster/src/layouts/TabLayout.vue?vue&type=script&lang=js","dependencies":[{"path":"/Users/shuguang/Desktop/毕设/CodeMaster/CodeMaster/src/layouts/TabLayout.vue","mtime":1743945250914},{"path":"/Users/shuguang/Desktop/毕设/CodeMaster/CodeMaster/node_modules/cache-loader/dist/cjs.js","mtime":1743264595665},{"path":"/Users/shuguang/Desktop/毕设/CodeMaster/CodeMaster/node_modules/babel-loader/lib/index.js","mtime":1743264596348},{"path":"/Users/shuguang/Desktop/毕设/CodeMaster/CodeMaster/node_modules/cache-loader/dist/cjs.js","mtime":1743264595665},{"path":"/Users/shuguang/Desktop/毕设/CodeMaster/CodeMaster/node_modules/vue-loader/lib/index.js","mtime":1743264596512}],"contextDependencies":[],"result":[{"type":"Buffer","data":"base64:CmltcG9ydCB7IG1lc3NhZ2UgfSBmcm9tICJhbnQtZGVzaWduLXZ1ZSI7CmltcG9ydCB7IGxhc3QgfSBmcm9tICJsb2Rhc2gtZXMiOwppbXBvcnQgQ29udGV4dE1lbnUgZnJvbSAiLi4vY29tcG9uZW50cy9jb21tb24vQ29udGV4dE1lbnUiOwppbXBvcnQgUGFnZVRvZ2dsZVRyYW5zaXRpb24gZnJvbSAiLi4vY29tcG9uZW50cy90cmFuc2l0aW9uL1BhZ2VUb2dnbGVUcmFuc2l0aW9uIjsKCmV4cG9ydCBkZWZhdWx0IHsKICBuYW1lOiAiVGFiTGF5b3V0IiwKICBjb21wb25lbnRzOiB7IFBhZ2VUb2dnbGVUcmFuc2l0aW9uLCBDb250ZXh0TWVudSB9LAogIGRhdGEoKSB7CiAgICByZXR1cm4gewogICAgICBwYWdlTGlzdDogW10sCiAgICAgIGR1c3RiaW46IFtdLAogICAgICBhY3RpdmVQYWdlOiAiIiwKICAgICAgbWVudVZpc2libGU6IGZhbHNlLAogICAgICBtZW51SXRlbXM6IFsKICAgICAgICB7IGtleTogIjEiLCBpY29uOiAiYXJyb3ctbGVmdCIsIHRleHQ6ICLlhbPpl63lt6bkvqciIH0sCiAgICAgICAgeyBrZXk6ICIyIiwgaWNvbjogImFycm93LXJpZ2h0IiwgdGV4dDogIuWFs+mXreWPs+S+pyIgfSwKICAgICAgICB7IGtleTogIjMiLCBpY29uOiAiY2xvc2UiLCB0ZXh0OiAi5YWz6Zet5YW25a6DIiB9LAogICAgICBdLAogICAgfTsKICB9LAogIHdhdGNoOiB7CiAgICAkcm91dGU6IHsKICAgICAgaW1tZWRpYXRlOiB0cnVlLAogICAgICBoYW5kbGVyKHJvdXRlKSB7CiAgICAgICAgdGhpcy5hY3RpdmVQYWdlID0gcm91dGUuZnVsbFBhdGg7CiAgICAgICAgdGhpcy5wdXRDYWNoZShyb3V0ZSk7CiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLnBhZ2VMaXN0LmZpbmRJbmRleCgKICAgICAgICAgIChpdGVtKSA9PiBpdGVtLmZ1bGxQYXRoID09PSByb3V0ZS5mdWxsUGF0aAogICAgICAgICk7CiAgICAgICAgaWYgKGluZGV4ID09PSAtMSkgewogICAgICAgICAgdGhpcy5wYWdlTGlzdC5wdXNoKHJvdXRlKTsKICAgICAgICB9CiAgICAgIH0sCiAgICB9LAogIH0sCiAgbWV0aG9kczogewogICAgbG9nKGRhdGEpIHsKICAgICAgY29uc29sZS5sb2coZGF0YSk7CiAgICB9LAogICAgY2hhbmdlUGFnZShrZXkpIHsKICAgICAgdGhpcy5hY3RpdmVQYWdlID0ga2V5OwogICAgICB0aGlzLiRyb3V0ZXIucHVzaChrZXkpOwogICAgfSwKICAgIGVkaXRQYWdlKGtleSwgYWN0aW9uKSB7CiAgICAgIGlmIChhY3Rpb24gPT09ICJyZW1vdmUiKSB7CiAgICAgICAgdGhpcy5yZW1vdmUoa2V5KTsKICAgICAgfQogICAgfSwKICAgIHJlbW92ZShrZXkpIHsKICAgICAgaWYgKHRoaXMucGFnZUxpc3QubGVuZ3RoIDw9IDEpIHsKICAgICAgICByZXR1cm4gbWVzc2FnZS5pbmZvKCLmnIDlkI7kuIDpobXkuoblk6Z+Iik7CiAgICAgIH0KICAgICAgbGV0IGN1ckluZGV4ID0gdGhpcy5wYWdlTGlzdC5maW5kSW5kZXgoKGl0ZW0pID0+IGl0ZW0uZnVsbFBhdGggPT09IGtleSk7CiAgICAgIGNvbnN0IHsgbWF0Y2hlZCB9ID0gdGhpcy5wYWdlTGlzdFtjdXJJbmRleF07CiAgICAgIGNvbnN0IGNvbXBvbmVudE5hbWUgPSBsYXN0KG1hdGNoZWQpLmNvbXBvbmVudHMuZGVmYXVsdC5uYW1lOwogICAgICB0aGlzLmR1c3RiaW4ucHVzaChjb21wb25lbnROYW1lKTsKICAgICAgdGhpcy5wYWdlTGlzdC5zcGxpY2UoY3VySW5kZXgsIDEpOwogICAgICAvLyDlpoLmnpzliKDpmaTnmoTmmK/lvZPliY3pobXmiY3pnIDopoHot7PovawKICAgICAgaWYgKGtleSA9PT0gdGhpcy5hY3RpdmVQYWdlKSB7CiAgICAgICAgLy8g5Yik5pat5ZCR5bem6Lez6L+Y5piv5ZCR5Y+z6LezCiAgICAgICAgY3VySW5kZXggPQogICAgICAgICAgY3VySW5kZXggPj0gdGhpcy5wYWdlTGlzdC5sZW5ndGgKICAgICAgICAgICAgPyB0aGlzLnBhZ2VMaXN0Lmxlbmd0aCAtIDEKICAgICAgICAgICAgOiBjdXJJbmRleDsKICAgICAgICBjb25zdCBwYWdlID0gdGhpcy5wYWdlTGlzdFtjdXJJbmRleF07CiAgICAgICAgdGhpcy4kcm91dGVyLnB1c2gocGFnZS5mdWxsUGF0aCkuZmluYWxseSgoKSA9PiB7CiAgICAgICAgICB0aGlzLmR1c3RiaW4uc3BsaWNlKDApOyAvLyDph43nva7vvIzlkKbliJnkvJrlvbHlk43liLDmn5Dkupvnu4Tku7bnmoTnvJPlrZgKICAgICAgICB9KTsKICAgICAgfQogICAgfSwKICAgIC8qKgogICAgICog5Y+z6ZSu6I+c5Y2VCiAgICAgKi8KICAgIG9uQ29udGV4dG1lbnUoZSkgewogICAgICBjb25zdCBrZXkgPSBnZXRUYWJLZXkoZS50YXJnZXQpOwogICAgICBpZiAoIWtleSkgcmV0dXJuOwoKICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpOwogICAgICB0aGlzLm1lbnVWaXNpYmxlID0gdHJ1ZTsKICAgIH0sCiAgICBvbk1lbnVTZWxlY3Qoa2V5LCB0YXJnZXQpIHsKICAgICAgY29uc3QgdGFiS2V5ID0gZ2V0VGFiS2V5KHRhcmdldCk7CiAgICAgIHN3aXRjaCAoa2V5KSB7CiAgICAgICAgY2FzZSAiMSI6CiAgICAgICAgICB0aGlzLmNsb3NlTGVmdCh0YWJLZXkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAiMiI6CiAgICAgICAgICB0aGlzLmNsb3NlUmlnaHQodGFiS2V5KTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgIjMiOgogICAgICAgICAgdGhpcy5jbG9zZU90aGVycyh0YWJLZXkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9LAogICAgY2xvc2VPdGhlcnModGFiS2V5KSB7CiAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5wYWdlTGlzdC5maW5kSW5kZXgoKGl0ZW0pID0+IGl0ZW0uZnVsbFBhdGggPT09IHRhYktleSk7CiAgICAgIGZvciAoY29uc3Qgcm91dGUgb2YgdGhpcy5wYWdlTGlzdCkgewogICAgICAgIGlmIChyb3V0ZS5mdWxsUGF0aCAhPT0gdGFiS2V5KSB7CiAgICAgICAgICB0aGlzLmNsZWFyQ2FjaGUocm91dGUpOwogICAgICAgIH0KICAgICAgfQogICAgICBjb25zdCBwYWdlID0gdGhpcy5wYWdlTGlzdFtpbmRleF07CiAgICAgIHRoaXMucGFnZUxpc3QgPSBbcGFnZV07CiAgICAgIHRoaXMuYWN0aXZlUGFnZSA9IHBhZ2UuZnVsbFBhdGg7CiAgICAgIHRoaXMuJHJvdXRlci5wdXNoKHRoaXMuYWN0aXZlUGFnZSkuY2F0Y2goKGUpID0+IGUpOwogICAgfSwKICAgIGNsb3NlTGVmdCh0YWJLZXkpIHsKICAgICAgY29uc3QgaW5kZXggPSB0aGlzLnBhZ2VMaXN0LmZpbmRJbmRleCgoaXRlbSkgPT4gaXRlbS5mdWxsUGF0aCA9PT0gdGFiS2V5KTsKICAgICAgdGhpcy5wYWdlTGlzdC5mb3JFYWNoKChyb3V0ZSwgaSkgPT4gewogICAgICAgIGlmIChpIDwgaW5kZXgpIHsKICAgICAgICAgIHRoaXMuY2xlYXJDYWNoZShyb3V0ZSk7CiAgICAgICAgfQogICAgICB9KTsKICAgICAgY29uc3QgcmVzdFBhZ2VzID0gdGhpcy5wYWdlTGlzdC5zbGljZShpbmRleCk7CiAgICAgIHRoaXMucGFnZUxpc3QgPSByZXN0UGFnZXM7CiAgICAgIC8vIOWIpOaWreW9k+WJjWFjdGl2ZVBhZ2XmmK/lkKblnKjlsIbopoHliKDpmaTnmoTpobXpnaLkuK0KICAgICAgY29uc3QgY3VyQWN0aXZlUGFnZSA9IHJlc3RQYWdlcy5maW5kKAogICAgICAgIChpdGVtKSA9PiBpdGVtLmZ1bGxQYXRoID09PSB0aGlzLmFjdGl2ZVBhZ2UKICAgICAgKTsKICAgICAgaWYgKCFjdXJBY3RpdmVQYWdlKSB7CiAgICAgICAgdGhpcy5hY3RpdmVQYWdlID0gcmVzdFBhZ2VzWzBdLmZ1bGxQYXRoOwogICAgICAgIHRoaXMuJHJvdXRlci5wdXNoKHRoaXMuYWN0aXZlUGFnZSkuY2F0Y2goKGUpID0+IGUpOwogICAgICB9CiAgICB9LAogICAgY2xvc2VSaWdodCh0YWJLZXkpIHsKICAgICAgY29uc3QgaW5kZXggPSB0aGlzLnBhZ2VMaXN0LmZpbmRJbmRleCgoaXRlbSkgPT4gaXRlbS5mdWxsUGF0aCA9PT0gdGFiS2V5KTsKICAgICAgdGhpcy5wYWdlTGlzdC5mb3JFYWNoKChyb3V0ZSwgaSkgPT4gewogICAgICAgIGlmIChpID4gaW5kZXgpIHsKICAgICAgICAgIHRoaXMuY2xlYXJDYWNoZShyb3V0ZSk7CiAgICAgICAgfQogICAgICB9KTsKICAgICAgY29uc3QgcmVzdFBhZ2VzID0gdGhpcy5wYWdlTGlzdC5zbGljZSgwLCBpbmRleCArIDEpOwogICAgICB0aGlzLnBhZ2VMaXN0ID0gcmVzdFBhZ2VzOwogICAgICAvLyDliKTmlq3lvZPliY1hY3RpdmVQYWdl5piv5ZCm5Zyo5bCG6KaB5Yig6Zmk55qE6aG16Z2i5LitCiAgICAgIGNvbnN0IGN1ckFjdGl2ZVBhZ2UgPSByZXN0UGFnZXMuZmluZCgKICAgICAgICAoaXRlbSkgPT4gaXRlbS5mdWxsUGF0aCA9PT0gdGhpcy5hY3RpdmVQYWdlCiAgICAgICk7CiAgICAgIGlmICghY3VyQWN0aXZlUGFnZSkgewogICAgICAgIHRoaXMuYWN0aXZlUGFnZSA9IGxhc3QocmVzdFBhZ2VzKS5mdWxsUGF0aDsKICAgICAgICB0aGlzLiRyb3V0ZXIucHVzaCh0aGlzLmFjdGl2ZVBhZ2UpLmNhdGNoKChlKSA9PiBlKTsKICAgICAgfQogICAgfSwKICAgIC8qKgogICAgICog57yT5a2Y5o6n5Yi2CiAgICAgKi8KICAgIGNsZWFyQ2FjaGUocm91dGUpIHsKICAgICAgY29uc3QgY29tcG9uZW50TmFtZSA9IGxhc3Qocm91dGUubWF0Y2hlZCkuY29tcG9uZW50cy5kZWZhdWx0Lm5hbWU7CiAgICAgIHRoaXMuZHVzdGJpbi5wdXNoKGNvbXBvbmVudE5hbWUpOyAvLyDmuIXpmaQKICAgIH0sCiAgICBwdXRDYWNoZShyb3V0ZSkgewogICAgICBjb25zdCBjb21wb25lbnROYW1lID0gbGFzdChyb3V0ZS5tYXRjaGVkKS5jb21wb25lbnRzLmRlZmF1bHQubmFtZTsKICAgICAgaWYgKHRoaXMuZHVzdGJpbi5pbmNsdWRlcyhjb21wb25lbnROYW1lKSkgewogICAgICAgIHRoaXMuZHVzdGJpbiA9IHRoaXMuZHVzdGJpbi5maWx0ZXIoKGl0ZW0pID0+IGl0ZW0gIT09IGNvbXBvbmVudE5hbWUpOwogICAgICB9CiAgICB9LAogIH0sCn07CgovKioKICog6I635Y+WVGFi5qCH562+5LiLZG9t6IqC54K55Lit6Ieq5a6a5LmJ55qE5pWw5o2u77yM6YCS5b2S5ZCR5LiL5p+l5om+5pyA5aSaM+Wxgu+8iOinguWvn1RhYue7hOS7tua4suafk+WQjueahERPTeW+l+WHuu+8iQogKiDor6XmlrnlvI/lsZ7kuo5oYWNr5omL5q6177yM5LiN5b6X5bey5Li65LmLCiAqIEBwYXJhbXtIVE1MRWxlbWVudH0gdGFyZ2V0IGV2ZW50LnRhcmdldAogKiBAcGFyYW0gZGVwdGgg5rex5bqmCiAqLwpmdW5jdGlvbiBnZXRUYWJLZXkodGFyZ2V0LCBkZXB0aCA9IDApIHsKICBpZiAoZGVwdGggPiAyIHx8ICF0YXJnZXQpIHsKICAgIHJldHVybiBudWxsOwogIH0KICByZXR1cm4gdGFyZ2V0LmRhdGFzZXQua2V5IHx8IGdldFRhYktleSh0YXJnZXQuZmlyc3RFbGVtZW50Q2hpbGQsICsrZGVwdGgpOwp9Cg=="},{"version":3,"sources":["TabLayout.vue"],"names":[],"mappings":";AAiCA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"TabLayout.vue","sourceRoot":"src/layouts","sourcesContent":["<template>\n <div class=\"tab-layout\">\n <a-tabs\n type=\"editable-card\"\n class=\"tab-bar\"\n :hide-add=\"true\"\n :active-key=\"activePage\"\n @change=\"changePage\"\n @edit=\"editPage\"\n @contextmenu=\"onContextmenu\"\n >\n <a-tab-pane v-for=\"page in pageList\" :key=\"page.fullPath\">\n <template #tab>\n <span :data-key=\"page.fullPath\">\n {{ page.meta.title }}\n </span>\n </template>\n </a-tab-pane>\n </a-tabs>\n <PageToggleTransition name=\"fadeIn\">\n <keep-alive :exclude=\"dustbin\">\n <router-view />\n </keep-alive>\n </PageToggleTransition>\n <ContextMenu\n :list=\"menuItems\"\n :visible.sync=\"menuVisible\"\n @select=\"onMenuSelect\"\n />\n </div>\n</template>\n\n<script>\nimport { message } from \"ant-design-vue\";\nimport { last } from \"lodash-es\";\nimport ContextMenu from \"../components/common/ContextMenu\";\nimport PageToggleTransition from \"../components/transition/PageToggleTransition\";\n\nexport default {\n name: \"TabLayout\",\n components: { PageToggleTransition, ContextMenu },\n data() {\n return {\n pageList: [],\n dustbin: [],\n activePage: \"\",\n menuVisible: false,\n menuItems: [\n { key: \"1\", icon: \"arrow-left\", text: \"关闭左侧\" },\n { key: \"2\", icon: \"arrow-right\", text: \"关闭右侧\" },\n { key: \"3\", icon: \"close\", text: \"关闭其它\" },\n ],\n };\n },\n watch: {\n $route: {\n immediate: true,\n handler(route) {\n this.activePage = route.fullPath;\n this.putCache(route);\n const index = this.pageList.findIndex(\n (item) => item.fullPath === route.fullPath\n );\n if (index === -1) {\n this.pageList.push(route);\n }\n },\n },\n },\n methods: {\n log(data) {\n console.log(data);\n },\n changePage(key) {\n this.activePage = key;\n this.$router.push(key);\n },\n editPage(key, action) {\n if (action === \"remove\") {\n this.remove(key);\n }\n },\n remove(key) {\n if (this.pageList.length <= 1) {\n return message.info(\"最后一页了哦~\");\n }\n let curIndex = this.pageList.findIndex((item) => item.fullPath === key);\n const { matched } = this.pageList[curIndex];\n const componentName = last(matched).components.default.name;\n this.dustbin.push(componentName);\n this.pageList.splice(curIndex, 1);\n // 如果删除的是当前页才需要跳转\n if (key === this.activePage) {\n // 判断向左跳还是向右跳\n curIndex =\n curIndex >= this.pageList.length\n ? this.pageList.length - 1\n : curIndex;\n const page = this.pageList[curIndex];\n this.$router.push(page.fullPath).finally(() => {\n this.dustbin.splice(0); // 重置,否则会影响到某些组件的缓存\n });\n }\n },\n /**\n * 右键菜单\n */\n onContextmenu(e) {\n const key = getTabKey(e.target);\n if (!key) return;\n\n e.preventDefault();\n this.menuVisible = true;\n },\n onMenuSelect(key, target) {\n const tabKey = getTabKey(target);\n switch (key) {\n case \"1\":\n this.closeLeft(tabKey);\n break;\n case \"2\":\n this.closeRight(tabKey);\n break;\n case \"3\":\n this.closeOthers(tabKey);\n break;\n default:\n break;\n }\n },\n closeOthers(tabKey) {\n const index = this.pageList.findIndex((item) => item.fullPath === tabKey);\n for (const route of this.pageList) {\n if (route.fullPath !== tabKey) {\n this.clearCache(route);\n }\n }\n const page = this.pageList[index];\n this.pageList = [page];\n this.activePage = page.fullPath;\n this.$router.push(this.activePage).catch((e) => e);\n },\n closeLeft(tabKey) {\n const index = this.pageList.findIndex((item) => item.fullPath === tabKey);\n this.pageList.forEach((route, i) => {\n if (i < index) {\n this.clearCache(route);\n }\n });\n const restPages = this.pageList.slice(index);\n this.pageList = restPages;\n // 判断当前activePage是否在将要删除的页面中\n const curActivePage = restPages.find(\n (item) => item.fullPath === this.activePage\n );\n if (!curActivePage) {\n this.activePage = restPages[0].fullPath;\n this.$router.push(this.activePage).catch((e) => e);\n }\n },\n closeRight(tabKey) {\n const index = this.pageList.findIndex((item) => item.fullPath === tabKey);\n this.pageList.forEach((route, i) => {\n if (i > index) {\n this.clearCache(route);\n }\n });\n const restPages = this.pageList.slice(0, index + 1);\n this.pageList = restPages;\n // 判断当前activePage是否在将要删除的页面中\n const curActivePage = restPages.find(\n (item) => item.fullPath === this.activePage\n );\n if (!curActivePage) {\n this.activePage = last(restPages).fullPath;\n this.$router.push(this.activePage).catch((e) => e);\n }\n },\n /**\n * 缓存控制\n */\n clearCache(route) {\n const componentName = last(route.matched).components.default.name;\n this.dustbin.push(componentName); // 清除\n },\n putCache(route) {\n const componentName = last(route.matched).components.default.name;\n if (this.dustbin.includes(componentName)) {\n this.dustbin = this.dustbin.filter((item) => item !== componentName);\n }\n },\n },\n};\n\n/**\n * 获取Tab标签下dom节点中自定义的数据递归向下查找最多3层观察Tab组件渲染后的DOM得出\n * 该方式属于hack手段不得已为之\n * @param{HTMLElement} target event.target\n * @param depth 深度\n */\nfunction getTabKey(target, depth = 0) {\n if (depth > 2 || !target) {\n return null;\n }\n return target.dataset.key || getTabKey(target.firstElementChild, ++depth);\n}\n</script>\n\n<style lang=\"less\" scoped>\n.tab-layout {\n background: #fff;\n padding: 6px 4px 0;\n margin-bottom: 10px;\n height: 32px !important;\n\n .tab-bar {\n background: #fff;\n margin-bottom: 10px;\n :deep(.ant-tabs-bar) {\n margin: 0;\n border: none;\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);\n }\n\n :deep(.ant-tabs-nav-container) {\n height: 32px !important;\n }\n\n :deep(.ant-tabs-tab) {\n margin-right: 6px;\n height: 32px !important;\n line-height: 32px !important;\n background: #fafafa;\n border: 1px solid #f0f0f0;\n border-radius: 4px;\n transition: all 0.3s;\n padding: 0 16px;\n\n &:hover {\n color: #1890ff;\n background: #e6f7ff;\n }\n\n &.ant-tabs-tab-active {\n background: #fff;\n border-color: #1890ff;\n color: #1890ff;\n }\n\n .ant-tabs-close-x {\n width: 16px;\n height: 16px;\n line-height: 16px;\n margin-right: -4px;\n margin-left: 4px;\n opacity: 0.45;\n\n &:hover {\n opacity: 1;\n color: #ff4d4f;\n }\n }\n }\n\n :deep(.ant-tabs-ink-bar) {\n display: none;\n }\n }\n}\n\n.breadcrumb {\n margin-bottom: 12px;\n padding: 8px 24px;\n background: #fff;\n border-radius: 4px;\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);\n}\n\n// 右键菜单样式优化\n:deep(.context-menu) {\n background: #fff;\n border-radius: 4px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n\n .menu-item {\n padding: 8px 16px;\n cursor: pointer;\n transition: all 0.3s;\n\n &:hover {\n background: #e6f7ff;\n color: #1890ff;\n }\n\n .anticon {\n margin-right: 8px;\n }\n }\n}\n</style>\n"]}]}