index.vue 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. <template>
  2. <div class="vab-tabs">
  3. <div
  4. class="vab-tabs-left-panel"
  5. :style="
  6. this.$route.path === '/index/index'
  7. ? 'border-bottom: 1px solid rgba(0, 0, 0, 0.04);'
  8. : ''
  9. "
  10. >
  11. <!-- 缩进按钮 start -->
  12. <!-- <div
  13. style="
  14. display: inline-block;
  15. float: left;
  16. margin-top: 14px;
  17. margin-right: 11px;
  18. "
  19. >
  20. <menu-unfold-outlined
  21. v-if="collapse"
  22. class="trigger"
  23. @click="toggleCollapse"
  24. />
  25. <menu-fold-outlined v-else class="trigger" @click="toggleCollapse" />
  26. </div> -->
  27. <!-- 缩进按钮 start -->
  28. <!-- 面包屑start -->
  29. <!-- <el-breadcrumb separator="/" style="display: inline-block">
  30. <el-breadcrumb-item
  31. v-for="(item, ind) in breadListLast"
  32. :key="ind"
  33. :to="item.path"
  34. >
  35. {{ item.title }}
  36. </el-breadcrumb-item>
  37. </el-breadcrumb> -->
  38. <!-- <el-breadcrumb separator="/">
  39. <el-breadcrumb-item
  40. v-for="(item, ind) in breadListLast"
  41. :key="ind"
  42. :to="item.path"
  43. >
  44. {{ item.title }}
  45. </el-breadcrumb-item>
  46. </el-breadcrumb> -->
  47. <!-- {{visitedRoutes}} -->
  48. <a-tabs
  49. @tab-click="handleTabClick"
  50. @edit="handleTabRemove"
  51. v-model:activeKey="tabActive"
  52. hide-add
  53. type="editable-card"
  54. >
  55. <a-tab-pane
  56. v-for="item in visitedRoutes"
  57. :key="item.fullPath"
  58. :closable="!isAffix(item)"
  59. :tab="item.meta.title"
  60. ></a-tab-pane>
  61. </a-tabs>
  62. </div>
  63. <div class="version-header" v-if="this.$route.path === '/index'">
  64. <div style="width: 50%">
  65. <el-select
  66. v-model="this.$store.state.siteId"
  67. class="m-2"
  68. placeholder="Select"
  69. size="large"
  70. style="width: 280px; margin-top: 7.5px"
  71. >
  72. <el-option
  73. v-for="item in this.$store.state.siteList"
  74. :key="item.id"
  75. :label="item.siteName"
  76. :value="item.id"
  77. />
  78. </el-select>
  79. </div>
  80. <div style="width: 50%; text-align: right; user-select: none">
  81. {{ time }}
  82. </div>
  83. </div>
  84. <!-- 面包屑end -->
  85. <!-- <div class="vab-tabs-right-panel">
  86. <a-dropdown>
  87. <template v-slot:overlay>
  88. <a-menu @click="handleClick">
  89. <a-menu-item key="closeOthersTabs">
  90. <a>关闭其他</a>
  91. </a-menu-item>
  92. <a-menu-item key="closeLeftTabs">
  93. <a>关闭左侧</a>
  94. </a-menu-item>
  95. <a-menu-item key="closeRightTabs">
  96. <a>关闭右侧</a>
  97. </a-menu-item>
  98. <a-menu-item key="closeAllTabs">
  99. <a>关闭全部</a>
  100. </a-menu-item>
  101. </a-menu>
  102. </template>
  103. <a-button style="margin-left: 8px">
  104. 更多
  105. <DownOutlined />
  106. </a-button>
  107. </a-dropdown>
  108. </div> -->
  109. </div>
  110. </template>
  111. <script>
  112. // import { DownOutlined } from '@ant-design/icons-vue'
  113. import { mapActions, mapGetters, useStore } from 'vuex'
  114. // import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons-vue'
  115. export default {
  116. name: 'VabTabs',
  117. components: {
  118. // DownOutlined,
  119. // MenuUnfoldOutlined,
  120. // MenuFoldOutlined,
  121. },
  122. data() {
  123. return {
  124. breadListLast: [],
  125. affixTabs: [],
  126. tabActive: null,
  127. created: false,
  128. time: '',
  129. }
  130. },
  131. computed: {
  132. ...mapGetters({
  133. visitedRoutes: 'tagsBar/visitedRoutes',
  134. routes: 'routes/routes',
  135. }),
  136. },
  137. watch: {
  138. $route(route) {
  139. this.loadChange()
  140. this.addTabs(route)
  141. },
  142. },
  143. mounted() {
  144. const store = useStore()
  145. setInterval(() => {
  146. store.commit('getTimeAll')
  147. var time = store.state.Time_All
  148. this.time =
  149. time[0] +
  150. '年' +
  151. (time[1] < 9 ? '0' + (time[1] + 1) : time[1] + 1) +
  152. '月' +
  153. (time[2] < 10 ? '0' + time[2] : time[2]) +
  154. '日 ' +
  155. (time[3] < 10 ? '0' + time[3] : time[3]) +
  156. ':' +
  157. (time[4] < 10 ? '0' + time[4] : time[4]) +
  158. ':' +
  159. (time[5] < 10 ? '0' + time[5] : time[5])
  160. }, 0)
  161. },
  162. created() {
  163. this.initAffixTabs(this.routes)
  164. this.addTabs(this.$route)
  165. this.loadChange()
  166. },
  167. methods: {
  168. loadChange() {
  169. this.breadListLast = []
  170. this.$route.matched.map((val) => {
  171. this.breadListLast.push({
  172. path: val.path,
  173. title: val.meta.title,
  174. })
  175. })
  176. },
  177. ...mapActions({
  178. addVisitedRoute: 'tagsBar/addVisitedRoute',
  179. delVisitedRoute: 'tagsBar/delVisitedRoute',
  180. delOthersVisitedRoutes: 'tagsBar/delOthersVisitedRoutes',
  181. delLeftVisitedRoutes: 'tagsBar/delLeftVisitedRoutes',
  182. delRightVisitedRoutes: 'tagsBar/delRightVisitedRoutes',
  183. delAllVisitedRoutes: 'tagsBar/delAllVisitedRoutes',
  184. // toggleCollapse: 'settings/toggleCollapse',
  185. }),
  186. initAffixTabs(routes) {
  187. routes.forEach((route) => {
  188. if (route.meta && route.meta.affix) this.addTabs(route)
  189. if (route.children) this.initAffixTabs(route.children)
  190. })
  191. },
  192. async addTabs(tag) {
  193. console.log('tag')
  194. console.log(tag)
  195. if (tag.meta && tag.meta.title && tag.meta.tagHidden !== true) {
  196. let matched = [tag.name]
  197. if (tag.matched) matched = tag.matched.map((item) => item.name)
  198. await this.addVisitedRoute({
  199. path: tag.path,
  200. fullPath: tag.fullPath,
  201. query: tag.query,
  202. params: tag.params,
  203. name: tag.name,
  204. matched: matched,
  205. meta: { ...tag.meta },
  206. })
  207. this.tabActive = tag.fullPath
  208. }
  209. },
  210. isActive(route) {
  211. return route.path === this.$route.path
  212. },
  213. isAffix(tag) {
  214. return tag.meta && tag.meta.affix
  215. },
  216. handleTabClick(tab) {
  217. const route = this.visitedRoutes.filter((item) => item.path === tab)[0]
  218. if (this.$route.fullPath !== route.fullPath) this.$router.push(route)
  219. },
  220. async handleTabRemove(fullPath) {
  221. const view = this.visitedRoutes.find((item) => {
  222. return fullPath === item.fullPath
  223. })
  224. await this.delVisitedRoute(view)
  225. if (this.isActive(view)) this.toLastTag()
  226. },
  227. handleClick({ key }) {
  228. switch (key) {
  229. case 'closeOthersTabs':
  230. this.closeOthersTabs()
  231. break
  232. case 'closeLeftTabs':
  233. this.closeLeftTabs()
  234. break
  235. case 'closeRightTabs':
  236. this.closeRightTabs()
  237. break
  238. case 'closeAllTabs':
  239. this.closeAllTabs()
  240. break
  241. }
  242. },
  243. async closeSelectedTag(view) {
  244. await this.delVisitedRoute(view)
  245. if (this.isActive(view)) {
  246. this.toLastTag()
  247. }
  248. },
  249. async closeOthersTabs() {
  250. await this.delOthersVisitedRoutes(this.toThisTag())
  251. },
  252. async closeLeftTabs() {
  253. await this.delLeftVisitedRoutes(this.toThisTag())
  254. },
  255. async closeRightTabs() {
  256. await this.delRightVisitedRoutes(this.toThisTag())
  257. },
  258. async closeAllTabs() {
  259. await this.delAllVisitedRoutes()
  260. if (this.affixTabs.some((tag) => tag.path === this.toThisTag().path))
  261. return
  262. this.toLastTag()
  263. },
  264. toLastTag() {
  265. const latestView = this.visitedRoutes.slice(-1)[0]
  266. if (latestView) this.$router.push(latestView)
  267. else this.$router.push('/')
  268. },
  269. toThisTag() {
  270. const view = this.visitedRoutes.find(
  271. (item) => item.fullPath === this.$route.fullPath
  272. )
  273. if (this.$route.path !== view.path) this.$router.push(view)
  274. return view
  275. },
  276. },
  277. }
  278. </script>
  279. <style lang="less">
  280. .vab-tabs {
  281. // padding: 0 @vab-margin;
  282. background: #ffffff;
  283. overflow: hidden;
  284. &-left-panel {
  285. float: left;
  286. // width: calc(100% - 52px - @vab-margin - @vab-margin);
  287. width: 100%;
  288. padding: 0 @vab-margin;
  289. }
  290. &-right-panel {
  291. // float: left;
  292. width: 52px;
  293. }
  294. .version-header {
  295. display: flex;
  296. height: 50px;
  297. line-height: 50px;
  298. padding: 0 @vab-margin;
  299. }
  300. .ant-tabs {
  301. height: 50px;
  302. line-height: 50px;
  303. &-bar {
  304. // margin: 0 !important;
  305. margin-top: 9px;
  306. border-bottom: 0px solid red;
  307. }
  308. &-tab {
  309. height: 30px !important;
  310. margin-right: 5px !important;
  311. line-height: 30px !important;
  312. background: #ffffff !important;
  313. border: 1px solid #dedede !important;
  314. padding: 0 10px !important;
  315. }
  316. &-tab-prev,
  317. &-tab-next {
  318. height: 32px !important;
  319. line-height: 32px !important;
  320. }
  321. &-tab-active {
  322. border: 1px solid #1890ff !important;
  323. .ant-tabs-close-x {
  324. color: #1890ff !important;
  325. }
  326. }
  327. }
  328. // .el-breadcrumb {
  329. // height: @vab-breadcrumb-height;
  330. // line-height: @vab-breadcrumb-height;
  331. // }
  332. .el-breadcrumb {
  333. height: 36px;
  334. line-height: 36px;
  335. }
  336. }
  337. .ant-tabs-nav-container {
  338. font-size: 12px !important;
  339. }
  340. // .anticon[tabindex]{
  341. // position: relative;
  342. // top: -12px;
  343. // left:-5px
  344. // }
  345. </style>