1 line
14 KiB
JSON
1 line
14 KiB
JSON
{"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":1742646402773},{"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:CmltcG9ydCB7IG1lc3NhZ2UgfSBmcm9tICdhbnQtZGVzaWduLXZ1ZSc7CmltcG9ydCB7IGxhc3QgfSBmcm9tICdsb2Rhc2gtZXMnOwppbXBvcnQgQ29udGV4dE1lbnUgZnJvbSAnLi4vY29tcG9uZW50cy9jb21tb24vQ29udGV4dE1lbnUnOwppbXBvcnQgUGFnZVRvZ2dsZVRyYW5zaXRpb24gZnJvbSAnLi4vY29tcG9uZW50cy90cmFuc2l0aW9uL1BhZ2VUb2dnbGVUcmFuc2l0aW9uJzsKCmV4cG9ydCBkZWZhdWx0IHsKICBuYW1lOiAnVGFiTGF5b3V0JywKICBjb21wb25lbnRzOiB7IFBhZ2VUb2dnbGVUcmFuc2l0aW9uLCBDb250ZXh0TWVudSB9LAogIGRhdGEoKSB7CiAgICByZXR1cm4gewogICAgICBwYWdlTGlzdDogW10sCiAgICAgIGR1c3RiaW46IFtdLAogICAgICBhY3RpdmVQYWdlOiAnJywKICAgICAgbWVudVZpc2libGU6IGZhbHNlLAogICAgICBtZW51SXRlbXM6IFsKICAgICAgICB7IGtleTogJzEnLCBpY29uOiAnYXJyb3ctbGVmdCcsIHRleHQ6ICflhbPpl63lt6bkvqcnIH0sCiAgICAgICAgeyBrZXk6ICcyJywgaWNvbjogJ2Fycm93LXJpZ2h0JywgdGV4dDogJ+WFs+mXreWPs+S+pycgfSwKICAgICAgICB7IGtleTogJzMnLCBpY29uOiAnY2xvc2UnLCB0ZXh0OiAn5YWz6Zet5YW25a6DJyB9LAogICAgICBdLAogICAgfTsKICB9LAogIHdhdGNoOiB7CiAgICAkcm91dGU6IHsKICAgICAgaW1tZWRpYXRlOiB0cnVlLAogICAgICBoYW5kbGVyKHJvdXRlKSB7CiAgICAgICAgdGhpcy5hY3RpdmVQYWdlID0gcm91dGUuZnVsbFBhdGg7CiAgICAgICAgdGhpcy5wdXRDYWNoZShyb3V0ZSk7CiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLnBhZ2VMaXN0LmZpbmRJbmRleChpdGVtID0+IGl0ZW0uZnVsbFBhdGggPT09IHJvdXRlLmZ1bGxQYXRoKTsKICAgICAgICBpZiAoaW5kZXggPT09IC0xKSB7CiAgICAgICAgICB0aGlzLnBhZ2VMaXN0LnB1c2gocm91dGUpOwogICAgICAgIH0KICAgICAgfSwKICAgIH0sCiAgfSwKICBtZXRob2RzOiB7CiAgICBsb2coZGF0YSkgewogICAgICBjb25zb2xlLmxvZyhkYXRhKTsKICAgIH0sCiAgICBjaGFuZ2VQYWdlKGtleSkgewogICAgICB0aGlzLmFjdGl2ZVBhZ2UgPSBrZXk7CiAgICAgIHRoaXMuJHJvdXRlci5wdXNoKGtleSk7CiAgICB9LAogICAgZWRpdFBhZ2Uoa2V5LCBhY3Rpb24pIHsKICAgICAgaWYgKGFjdGlvbiA9PT0gJ3JlbW92ZScpIHsKICAgICAgICB0aGlzLnJlbW92ZShrZXkpOwogICAgICB9CiAgICB9LAogICAgcmVtb3ZlKGtleSkgewogICAgICBpZiAodGhpcy5wYWdlTGlzdC5sZW5ndGggPD0gMSkgewogICAgICAgIHJldHVybiBtZXNzYWdlLmluZm8oJ+acgOWQjuS4gOmhteS6huWTpn4nKTsKICAgICAgfQogICAgICBsZXQgY3VySW5kZXggPSB0aGlzLnBhZ2VMaXN0LmZpbmRJbmRleChpdGVtID0+IGl0ZW0uZnVsbFBhdGggPT09IGtleSk7CiAgICAgIGNvbnN0IHsgbWF0Y2hlZCB9ID0gdGhpcy5wYWdlTGlzdFtjdXJJbmRleF07CiAgICAgIGNvbnN0IGNvbXBvbmVudE5hbWUgPSBsYXN0KG1hdGNoZWQpLmNvbXBvbmVudHMuZGVmYXVsdC5uYW1lOwogICAgICB0aGlzLmR1c3RiaW4ucHVzaChjb21wb25lbnROYW1lKTsKICAgICAgdGhpcy5wYWdlTGlzdC5zcGxpY2UoY3VySW5kZXgsIDEpOwogICAgICAvLyDlpoLmnpzliKDpmaTnmoTmmK/lvZPliY3pobXmiY3pnIDopoHot7PovawKICAgICAgaWYgKGtleSA9PT0gdGhpcy5hY3RpdmVQYWdlKSB7CiAgICAgICAgLy8g5Yik5pat5ZCR5bem6Lez6L+Y5piv5ZCR5Y+z6LezCiAgICAgICAgY3VySW5kZXggPSBjdXJJbmRleCA+PSB0aGlzLnBhZ2VMaXN0Lmxlbmd0aCA/IHRoaXMucGFnZUxpc3QubGVuZ3RoIC0gMSA6IGN1ckluZGV4OwogICAgICAgIGNvbnN0IHBhZ2UgPSB0aGlzLnBhZ2VMaXN0W2N1ckluZGV4XTsKICAgICAgICB0aGlzLiRyb3V0ZXIucHVzaChwYWdlLmZ1bGxQYXRoKS5maW5hbGx5KCgpID0+IHsKICAgICAgICAgIHRoaXMuZHVzdGJpbi5zcGxpY2UoMCk7IC8vIOmHjee9ru+8jOWQpuWImeS8muW9seWTjeWIsOafkOS6m+e7hOS7tueahOe8k+WtmAogICAgICAgIH0pOwogICAgICB9CiAgICB9LAogICAgLyoqCiAgICAgKiDlj7PplK7oj5zljZUKICAgICAqLwogICAgb25Db250ZXh0bWVudShlKSB7CiAgICAgIGNvbnN0IGtleSA9IGdldFRhYktleShlLnRhcmdldCk7CiAgICAgIGlmICgha2V5KSByZXR1cm47CgogICAgICBlLnByZXZlbnREZWZhdWx0KCk7CiAgICAgIHRoaXMubWVudVZpc2libGUgPSB0cnVlOwogICAgfSwKICAgIG9uTWVudVNlbGVjdChrZXksIHRhcmdldCkgewogICAgICBjb25zdCB0YWJLZXkgPSBnZXRUYWJLZXkodGFyZ2V0KTsKICAgICAgc3dpdGNoIChrZXkpIHsKICAgICAgICBjYXNlICcxJzogdGhpcy5jbG9zZUxlZnQodGFiS2V5KTsgYnJlYWs7CiAgICAgICAgY2FzZSAnMic6IHRoaXMuY2xvc2VSaWdodCh0YWJLZXkpOyBicmVhazsKICAgICAgICBjYXNlICczJzogdGhpcy5jbG9zZU90aGVycyh0YWJLZXkpOyBicmVhazsKICAgICAgICBkZWZhdWx0OiBicmVhazsKICAgICAgfQogICAgfSwKICAgIGNsb3NlT3RoZXJzKHRhYktleSkgewogICAgICBjb25zdCBpbmRleCA9IHRoaXMucGFnZUxpc3QuZmluZEluZGV4KGl0ZW0gPT4gaXRlbS5mdWxsUGF0aCA9PT0gdGFiS2V5KTsKICAgICAgZm9yIChjb25zdCByb3V0ZSBvZiB0aGlzLnBhZ2VMaXN0KSB7CiAgICAgICAgaWYgKHJvdXRlLmZ1bGxQYXRoICE9PSB0YWJLZXkpIHsKICAgICAgICAgIHRoaXMuY2xlYXJDYWNoZShyb3V0ZSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIGNvbnN0IHBhZ2UgPSB0aGlzLnBhZ2VMaXN0W2luZGV4XTsKICAgICAgdGhpcy5wYWdlTGlzdCA9IFtwYWdlXTsKICAgICAgdGhpcy5hY3RpdmVQYWdlID0gcGFnZS5mdWxsUGF0aDsKICAgICAgdGhpcy4kcm91dGVyLnB1c2godGhpcy5hY3RpdmVQYWdlKS5jYXRjaChlID0+IGUpOwogICAgfSwKICAgIGNsb3NlTGVmdCh0YWJLZXkpIHsKICAgICAgY29uc3QgaW5kZXggPSB0aGlzLnBhZ2VMaXN0LmZpbmRJbmRleChpdGVtID0+IGl0ZW0uZnVsbFBhdGggPT09IHRhYktleSk7CiAgICAgIHRoaXMucGFnZUxpc3QuZm9yRWFjaCgocm91dGUsIGkpID0+IHsKICAgICAgICBpZiAoaSA8IGluZGV4KSB7CiAgICAgICAgICB0aGlzLmNsZWFyQ2FjaGUocm91dGUpOwogICAgICAgIH0KICAgICAgfSk7CiAgICAgIGNvbnN0IHJlc3RQYWdlcyA9IHRoaXMucGFnZUxpc3Quc2xpY2UoaW5kZXgpOwogICAgICB0aGlzLnBhZ2VMaXN0ID0gcmVzdFBhZ2VzOwogICAgICAvLyDliKTmlq3lvZPliY1hY3RpdmVQYWdl5piv5ZCm5Zyo5bCG6KaB5Yig6Zmk55qE6aG16Z2i5LitCiAgICAgIGNvbnN0IGN1ckFjdGl2ZVBhZ2UgPSByZXN0UGFnZXMuZmluZChpdGVtID0+IGl0ZW0uZnVsbFBhdGggPT09IHRoaXMuYWN0aXZlUGFnZSk7CiAgICAgIGlmICghY3VyQWN0aXZlUGFnZSkgewogICAgICAgIHRoaXMuYWN0aXZlUGFnZSA9IHJlc3RQYWdlc1swXS5mdWxsUGF0aDsKICAgICAgICB0aGlzLiRyb3V0ZXIucHVzaCh0aGlzLmFjdGl2ZVBhZ2UpLmNhdGNoKGUgPT4gZSk7CiAgICAgIH0KICAgIH0sCiAgICBjbG9zZVJpZ2h0KHRhYktleSkgewogICAgICBjb25zdCBpbmRleCA9IHRoaXMucGFnZUxpc3QuZmluZEluZGV4KGl0ZW0gPT4gaXRlbS5mdWxsUGF0aCA9PT0gdGFiS2V5KTsKICAgICAgdGhpcy5wYWdlTGlzdC5mb3JFYWNoKChyb3V0ZSwgaSkgPT4gewogICAgICAgIGlmIChpID4gaW5kZXgpIHsKICAgICAgICAgIHRoaXMuY2xlYXJDYWNoZShyb3V0ZSk7CiAgICAgICAgfQogICAgICB9KTsKICAgICAgY29uc3QgcmVzdFBhZ2VzID0gdGhpcy5wYWdlTGlzdC5zbGljZSgwLCBpbmRleCArIDEpOwogICAgICB0aGlzLnBhZ2VMaXN0ID0gcmVzdFBhZ2VzOwogICAgICAvLyDliKTmlq3lvZPliY1hY3RpdmVQYWdl5piv5ZCm5Zyo5bCG6KaB5Yig6Zmk55qE6aG16Z2i5LitCiAgICAgIGNvbnN0IGN1ckFjdGl2ZVBhZ2UgPSByZXN0UGFnZXMuZmluZChpdGVtID0+IGl0ZW0uZnVsbFBhdGggPT09IHRoaXMuYWN0aXZlUGFnZSk7CiAgICAgIGlmICghY3VyQWN0aXZlUGFnZSkgewogICAgICAgIHRoaXMuYWN0aXZlUGFnZSA9IGxhc3QocmVzdFBhZ2VzKS5mdWxsUGF0aDsKICAgICAgICB0aGlzLiRyb3V0ZXIucHVzaCh0aGlzLmFjdGl2ZVBhZ2UpLmNhdGNoKGUgPT4gZSk7CiAgICAgIH0KICAgIH0sCiAgICAvKioKICAgICAqIOe8k+WtmOaOp+WItgogICAgICovCiAgICBjbGVhckNhY2hlKHJvdXRlKSB7CiAgICAgIGNvbnN0IGNvbXBvbmVudE5hbWUgPSBsYXN0KHJvdXRlLm1hdGNoZWQpLmNvbXBvbmVudHMuZGVmYXVsdC5uYW1lOwogICAgICB0aGlzLmR1c3RiaW4ucHVzaChjb21wb25lbnROYW1lKTsgLy8g5riF6ZmkCiAgICB9LAogICAgcHV0Q2FjaGUocm91dGUpIHsKICAgICAgY29uc3QgY29tcG9uZW50TmFtZSA9IGxhc3Qocm91dGUubWF0Y2hlZCkuY29tcG9uZW50cy5kZWZhdWx0Lm5hbWU7CiAgICAgIGlmICh0aGlzLmR1c3RiaW4uaW5jbHVkZXMoY29tcG9uZW50TmFtZSkpIHsKICAgICAgICB0aGlzLmR1c3RiaW4gPSB0aGlzLmR1c3RiaW4uZmlsdGVyKGl0ZW0gPT4gaXRlbSAhPT0gY29tcG9uZW50TmFtZSk7CiAgICAgIH0KICAgIH0sCiAgfSwKfTsKCi8qKgogKiDojrflj5ZUYWLmoIfnrb7kuItkb23oioLngrnkuK3oh6rlrprkuYnnmoTmlbDmja7vvIzpgJLlvZLlkJHkuIvmn6Xmib7mnIDlpJoz5bGC77yI6KeC5a+fVGFi57uE5Lu25riy5p+T5ZCO55qERE9N5b6X5Ye677yJCiAqIOivpeaWueW8j+WxnuS6jmhhY2vmiYvmrrXvvIzkuI3lvpflt7LkuLrkuYsKICogQHBhcmFte0hUTUxFbGVtZW50fSB0YXJnZXQgZXZlbnQudGFyZ2V0CiAqIEBwYXJhbSBkZXB0aCDmt7HluqYKICovCmZ1bmN0aW9uIGdldFRhYktleSh0YXJnZXQsIGRlcHRoID0gMCkgewogIGlmIChkZXB0aCA+IDIgfHwgIXRhcmdldCkgewogICAgcmV0dXJuIG51bGw7CiAgfQogIHJldHVybiB0YXJnZXQuZGF0YXNldC5rZXkgfHwgZ2V0VGFiS2V5KHRhcmdldC5maXJzdEVsZW1lbnRDaGlsZCwgKytkZXB0aCk7Cn0K"},{"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;;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;;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(item => item.fullPath === route.fullPath);\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 = curIndex >= this.pageList.length ? this.pageList.length - 1 : 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': this.closeLeft(tabKey); break;\n case '2': this.closeRight(tabKey); break;\n case '3': this.closeOthers(tabKey); break;\n default: 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(item => item.fullPath === this.activePage);\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(item => item.fullPath === this.activePage);\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 scoped>\n.tab-bar >>> .ant-tabs-bar {\n margin-bottom: 0;\n}\n\n.breadcrumb {\n margin-bottom: 10px;\n}\n</style>\n\n"]}]} |