{"remainingRequest":"D:\\源码\\vue-element-admin-master\\node_modules\\vue-loader\\lib\\index.js??vue-loader-options!D:\\源码\\vue-element-admin-master\\src\\layout\\components\\TagsView\\index.vue?vue&type=style&index=1&lang=scss&","dependencies":[{"path":"D:\\源码\\vue-element-admin-master\\src\\layout\\components\\TagsView\\index.vue","mtime":1649647926000},{"path":"D:\\源码\\vue-element-admin-master\\node_modules\\css-loader\\dist\\cjs.js","mtime":499162500000},{"path":"D:\\源码\\vue-element-admin-master\\node_modules\\vue-loader\\lib\\loaders\\stylePostLoader.js","mtime":499162500000},{"path":"D:\\源码\\vue-element-admin-master\\node_modules\\postcss-loader\\src\\index.js","mtime":499162500000},{"path":"D:\\源码\\vue-element-admin-master\\node_modules\\sass-loader\\dist\\cjs.js","mtime":499162500000},{"path":"D:\\源码\\vue-element-admin-master\\node_modules\\cache-loader\\dist\\cjs.js","mtime":499162500000},{"path":"D:\\源码\\vue-element-admin-master\\node_modules\\vue-loader\\lib\\index.js","mtime":499162500000}],"contextDependencies":[],"result":[{"type":"Buffer","data":"base64:CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCi8vcmVzZXQgZWxlbWVudCBjc3Mgb2YgZWwtaWNvbi1jbG9zZQoudGFncy12aWV3LXdyYXBwZXIgewogIC50YWdzLXZpZXctaXRlbSB7CiAgICAuZWwtaWNvbi1jbG9zZSB7CiAgICAgIHdpZHRoOiAxNnB4OwogICAgICBoZWlnaHQ6IDE2cHg7CiAgICAgIHZlcnRpY2FsLWFsaWduOiAycHg7CiAgICAgIGJvcmRlci1yYWRpdXM6IDUwJTsKICAgICAgdGV4dC1hbGlnbjogY2VudGVyOwogICAgICB0cmFuc2l0aW9uOiBhbGwgLjNzIGN1YmljLWJlemllciguNjQ1LCAuMDQ1LCAuMzU1LCAxKTsKICAgICAgdHJhbnNmb3JtLW9yaWdpbjogMTAwJSA1MCU7CiAgICAgICY6YmVmb3JlIHsKICAgICAgICB0cmFuc2Zvcm06IHNjYWxlKC42KTsKICAgICAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7CiAgICAgICAgdmVydGljYWwtYWxpZ246IC0zcHg7CiAgICAgIH0KICAgICAgJjpob3ZlciB7CiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogI2I0YmNjYzsKICAgICAgICBjb2xvcjogI2ZmZjsKICAgICAgfQogICAgfQogIH0KfQo="},{"version":3,"sources":["index.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4QA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"index.vue","sourceRoot":"src/layout/components/TagsView","sourcesContent":["<template>\n <div id=\"tags-view-container\" class=\"tags-view-container\">\n <scroll-pane ref=\"scrollPane\" class=\"tags-view-wrapper\" @scroll=\"handleScroll\">\n <router-link\n v-for=\"tag in visitedViews\"\n ref=\"tag\"\n :key=\"tag.path\"\n :class=\"isActive(tag)?'active':''\"\n :to=\"{ path: tag.path, query: tag.query, fullPath: tag.fullPath }\"\n tag=\"span\"\n class=\"tags-view-item\"\n @click.middle.native=\"!isAffix(tag)?closeSelectedTag(tag):''\"\n @contextmenu.prevent.native=\"openMenu(tag,$event)\"\n >\n {{ tag.title }}\n <span v-if=\"!isAffix(tag)\" class=\"el-icon-close\" @click.prevent.stop=\"closeSelectedTag(tag)\" />\n </router-link>\n </scroll-pane>\n <ul v-show=\"visible\" :style=\"{left:left+'px',top:top+'px'}\" class=\"contextmenu\">\n <li @click=\"refreshSelectedTag(selectedTag)\">Refresh</li>\n <li v-if=\"!isAffix(selectedTag)\" @click=\"closeSelectedTag(selectedTag)\">Close</li>\n <li @click=\"closeOthersTags\">Close Others</li>\n <li @click=\"closeAllTags(selectedTag)\">Close All</li>\n </ul>\n </div>\n</template>\n\n<script>\nimport ScrollPane from './ScrollPane'\nimport path from 'path'\n\nexport default {\n components: { ScrollPane },\n data() {\n return {\n visible: false,\n top: 0,\n left: 0,\n selectedTag: {},\n affixTags: []\n }\n },\n computed: {\n visitedViews() {\n return this.$store.state.tagsView.visitedViews\n },\n routes() {\n return this.$store.state.permission.routes\n }\n },\n watch: {\n $route() {\n this.addTags()\n this.moveToCurrentTag()\n },\n visible(value) {\n if (value) {\n document.body.addEventListener('click', this.closeMenu)\n } else {\n document.body.removeEventListener('click', this.closeMenu)\n }\n }\n },\n mounted() {\n this.initTags()\n this.addTags()\n },\n methods: {\n isActive(route) {\n return route.path === this.$route.path\n },\n isAffix(tag) {\n return tag.meta && tag.meta.affix\n },\n filterAffixTags(routes, basePath = '/') {\n let tags = []\n routes.forEach(route => {\n if (route.meta && route.meta.affix) {\n const tagPath = path.resolve(basePath, route.path)\n tags.push({\n fullPath: tagPath,\n path: tagPath,\n name: route.name,\n meta: { ...route.meta }\n })\n }\n if (route.children) {\n const tempTags = this.filterAffixTags(route.children, route.path)\n if (tempTags.length >= 1) {\n tags = [...tags, ...tempTags]\n }\n }\n })\n return tags\n },\n initTags() {\n const affixTags = this.affixTags = this.filterAffixTags(this.routes)\n for (const tag of affixTags) {\n // Must have tag name\n if (tag.name) {\n this.$store.dispatch('tagsView/addVisitedView', tag)\n }\n }\n },\n addTags() {\n const { name } = this.$route\n if (name) {\n this.$store.dispatch('tagsView/addView', this.$route)\n }\n return false\n },\n moveToCurrentTag() {\n const tags = this.$refs.tag\n this.$nextTick(() => {\n for (const tag of tags) {\n if (tag.to.path === this.$route.path) {\n this.$refs.scrollPane.moveToTarget(tag)\n // when query is different then update\n if (tag.to.fullPath !== this.$route.fullPath) {\n this.$store.dispatch('tagsView/updateVisitedView', this.$route)\n }\n break\n }\n }\n })\n },\n refreshSelectedTag(view) {\n this.$store.dispatch('tagsView/delCachedView', view).then(() => {\n const { fullPath } = view\n this.$nextTick(() => {\n this.$router.replace({\n path: '/redirect' + fullPath\n })\n })\n })\n },\n closeSelectedTag(view) {\n this.$store.dispatch('tagsView/delView', view).then(({ visitedViews }) => {\n if (this.isActive(view)) {\n this.toLastView(visitedViews, view)\n }\n })\n },\n closeOthersTags() {\n this.$router.push(this.selectedTag)\n this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => {\n this.moveToCurrentTag()\n })\n },\n closeAllTags(view) {\n this.$store.dispatch('tagsView/delAllViews').then(({ visitedViews }) => {\n if (this.affixTags.some(tag => tag.path === view.path)) {\n return\n }\n this.toLastView(visitedViews, view)\n })\n },\n toLastView(visitedViews, view) {\n const latestView = visitedViews.slice(-1)[0]\n if (latestView) {\n this.$router.push(latestView.fullPath)\n } else {\n // now the default is to redirect to the home page if there is no tags-view,\n // you can adjust it according to your needs.\n if (view.name === 'Dashboard') {\n // to reload home page\n this.$router.replace({ path: '/redirect' + view.fullPath })\n } else {\n this.$router.push('/')\n }\n }\n },\n openMenu(tag, e) {\n const menuMinWidth = 105\n const offsetLeft = this.$el.getBoundingClientRect().left // container margin left\n const offsetWidth = this.$el.offsetWidth // container width\n const maxLeft = offsetWidth - menuMinWidth // left boundary\n const left = e.clientX - offsetLeft + 15 // 15: margin right\n\n if (left > maxLeft) {\n this.left = maxLeft\n } else {\n this.left = left\n }\n\n this.top = e.clientY\n this.visible = true\n this.selectedTag = tag\n },\n closeMenu() {\n this.visible = false\n },\n handleScroll() {\n this.closeMenu()\n }\n }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.tags-view-container {\n height: 34px;\n width: 100%;\n background: #fff;\n border-bottom: 1px solid #d8dce5;\n box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04);\n .tags-view-wrapper {\n .tags-view-item {\n display: inline-block;\n position: relative;\n cursor: pointer;\n height: 26px;\n line-height: 26px;\n border: 1px solid #d8dce5;\n color: #495060;\n background: #fff;\n padding: 0 8px;\n font-size: 12px;\n margin-left: 5px;\n margin-top: 4px;\n &:first-of-type {\n margin-left: 15px;\n }\n &:last-of-type {\n margin-right: 15px;\n }\n &.active {\n background-color: #42b983;\n color: #fff;\n border-color: #42b983;\n &::before {\n content: '';\n background: #fff;\n display: inline-block;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n position: relative;\n margin-right: 2px;\n }\n }\n }\n }\n .contextmenu {\n margin: 0;\n background: #fff;\n z-index: 3000;\n position: absolute;\n list-style-type: none;\n padding: 5px 0;\n border-radius: 4px;\n font-size: 12px;\n font-weight: 400;\n color: #333;\n box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);\n li {\n margin: 0;\n padding: 7px 16px;\n cursor: pointer;\n &:hover {\n background: #eee;\n }\n }\n }\n}\n</style>\n\n<style lang=\"scss\">\n//reset element css of el-icon-close\n.tags-view-wrapper {\n .tags-view-item {\n .el-icon-close {\n width: 16px;\n height: 16px;\n vertical-align: 2px;\n border-radius: 50%;\n text-align: center;\n transition: all .3s cubic-bezier(.645, .045, .355, 1);\n transform-origin: 100% 50%;\n &:before {\n transform: scale(.6);\n display: inline-block;\n vertical-align: -3px;\n }\n &:hover {\n background-color: #b4bccc;\n color: #fff;\n }\n }\n }\n}\n</style>\n"]}]}
|