1. <template>
  2. <section>
  3. <div class="navTabList el-tabs__nav-scroll" id="tabsNav" v-if="showTags">
  4. <ul class="nt-ul el-tabs__nav" id="tabsNavList">
  5. <li v-for="(item,index) in tagsList" :class="{'is-active': isActive(item.path)}" :key="index">
  6. <router-link :to="item.path" class="tags-li-title">
  7. {{item.title}}
  8. </router-link>
  9. <i class="el-tag__close el-icon-close" @click="closeTags(index)"></i></li>
  10. </ul>
  11. <div class="pull-right navTab_right">
  12. <el-button-group>
  13. <el-button size="mini" icon="el-icon-arrow-left" @click="tabsPrev()"></el-button>
  14. <el-button size="mini" icon="el-icon-arrow-right" @click="tabsNext()"></el-button>
  15. </el-button-group>
  16. <el-dropdown @command="handleTags">
  17. <el-button size="mini" type="primary">
  18. 标签选项
  19. <i class="el-icon-arrow-down el-icon--right"></i>
  20. </el-button>
  21. <el-dropdown-menu slot="dropdown">
  22. <el-dropdown-item command="other">关闭其他页面</el-dropdown-item>
  23. <el-dropdown-item command="all">关闭所有页面</el-dropdown-item>
  24. </el-dropdown-menu>
  25. </el-dropdown>
  26. </div>
  27. </div>
  28. </section>
  29. </template>
  30.  
  31. <script>
  32. import bus from './bus'
  33.  
  34. export default {
  35. data() {
  36. return {
  37. tagsList: [],
  38. counter: '0'
  39. }
  40. },
  41. methods: {
  42. tabsNext() {
  43. let tabNav = document.getElementById('tabsNav')
  44. let tabNavList = document.getElementById('tabsNavList')
  45. let tabNavW = tabNav.clientWidth
  46. let tabNavListW = tabNavList.clientWidth
  47. if (tabNavW < tabNavListW && this.counter + tabNavW - 210 < tabNavListW) {
  48. this.counter = parseInt(this.counter) + parseInt(tabNavW) - 210
  49. tabNavList.style.transform = 'translateX(' + '-' + this.counter + 'px)'
  50. } else {
  51. }
  52. },
  53. tabsPrev() {
  54. let tabNav = document.getElementById('tabsNav')
  55. let tabNavList = document.getElementById('tabsNavList')
  56. let tabNavW = tabNav.clientWidth
  57.  
  58. if (tabNavW <= this.counter + tabNavW - 210) {
  59. this.counter = parseInt(this.counter) - parseInt(tabNavW) + 210
  60. tabNavList.style.transform = 'translateX(' + '-' + this.counter + 'px)'
  61. } else if (this.counter !== 0) {
  62. this.counter = 0
  63. tabNavList.style.transform = 'translateX(' + '0' + 'px)'
  64. } else {
  65. }
  66. },
  67. isActive(path) {
  68. return path === this.$route.fullPath
  69. },
  70. // 关闭单个标签
  71. closeTags(index) {
  72. const delItem = this.tagsList.splice(index, 1)[0]
  73. const item = this.tagsList[index] ? this.tagsList[index] : this.tagsList[index - 1]
  74. if (item) {
  75. delItem.path === this.$route.fullPath && this.$router.push(item.path)
  76. } else {
  77. this.$router.push('/dashboard')
  78. }
  79. },
  80. // 关闭全部标签
  81. closeAll() {
  82. this.tagsList = []
  83. this.$router.push('/dashboard')
  84. },
  85. // 关闭其他标签
  86. closeOther() {
  87. const curItem = this.tagsList.filter(item => {
  88. return item.path === this.$route.fullPath
  89. })
  90. this.tagsList = curItem
  91. },
  92. // 设置标签
  93. setTags(route) {
  94. const isExist = this.tagsList.some(item => {
  95. return item.path === route.fullPath
  96. })
  97. if (!isExist) {
  98. if (this.tagsList.length >= 99) {
  99. this.tagsList.shift()
  100. }
  101. this.tagsList.unshift({
  102. title: route.meta.title,
  103. path: route.fullPath,
  104. name: route.matched[1].components.default.name
  105. })
  106. }
  107. // bus.$emit('tags', this.tagsList)
  108. },
  109. handleTags(command) {
  110. command === 'other' ? this.closeOther() : this.closeAll()
  111. }
  112. },
  113. computed: {
  114. showTags() {
  115. return this.tagsList.length > 0
  116. }
  117. },
  118. watch: {
  119. $route(newValue, oldValue) {
  120. this.setTags(newValue)
  121. }
  122. },
  123. created() {
  124. this.setTags(this.$route)
  125. // 监听关闭当前页面的标签页
  126. bus.$on('close_current_tags', () => {
  127. for (let i = 0, len = this.tagsList.length; i < len; i++) {
  128. const item = this.tagsList[i]
  129. if (item.path === this.$route.fullPath) {
  130. if (i < len - 1) {
  131. this.$router.push(this.tagsList[i + 1].path)
  132. } else if (i > 0) {
  133. this.$router.push(this.tagsList[i - 1].path)
  134. } else {
  135. this.$router.push('/dashboard')
  136. }
  137. this.tagsList.splice(i, 1)
  138. }
  139. }
  140. })
  141. }
  142. }
  143. </script>
  144.  
  145. <style scoped>
  146. .navTabList {
  147. padding-right: 210px;
  148. height: 34px;
  149. line-height: 34px;
  150. background: #f4f4f4;
  151. margin-bottom: 10px;
  152. font-size: 12px;
  153. background-color: white;
  154. box-shadow:0 5px 10px #ddd ;
  155. }
  156.  
  157. .navTabList .nt-ul {
  158. float: left;
  159. margin: 0;
  160. padding: 0;
  161. list-style: none;
  162. }
  163.  
  164. .navTabList .nt-ul li {
  165. display: inline-block;
  166. margin: 1px 5px 2px 1px;
  167. border-radius: 3px;
  168. font-size: 12px;
  169. overflow: hidden;
  170. cursor: pointer;
  171. height: 24px;
  172. line-height: 24px;
  173. border: 1px solid #e9eaec;
  174. background: #fff;
  175. padding: 2px 12px 0 12px;
  176. vertical-align: middle;
  177. color: #666;
  178. -webkit-transition: all 0.3s ease-in;
  179. -moz-transition: all 0.3s ease-in;
  180. transition: all 0.3s ease-in;
  181. }
  182.  
  183. .navTabList .nt-ul li:before {
  184. content: '';
  185. width: 1px;
  186. height: 23px;
  187. position: absolute;
  188. left: 0;
  189. top: 7px;
  190. border-right: 1px solid #e4e4e4;
  191. }
  192.  
  193. .navTabList .nt-ul li:first-child:before {
  194. display: none;
  195. }
  196.  
  197. .navTabList .nt-ul li i {
  198. position: relative;
  199. font-size: 12px;
  200. width: 0;
  201. height: 14px;
  202. vertical-align: middle;
  203. line-height: 15px;
  204. overflow: hidden;
  205. top: -1px;
  206. right: -10px;
  207. }
  208.  
  209. .navTabList .nt-ul li i {
  210. width: 14px;
  211. }
  212.  
  213. .navTabList .nt-ul li a {
  214. display: inline-block;
  215. color: #999;
  216. }
  217.  
  218. .navTabList .nt-ul .is-active {
  219. padding: 0 13px;
  220. /*margin-top: 2px;*/
  221. height: 30px;
  222. line-height: 30px;
  223. border-top-left-radius: 3px;
  224. border-top-right-radius: 3px;
  225. background: #409eff;
  226. font-weight: bold;
  227. color: white;
  228. }
  229. .navTabList .nt-ul .is-active a{
  230. color: white;
  231. }
  232.  
  233. .navTabList .nt-ul .is-active:before {
  234. display: none;
  235. }
  236.  
  237. .navTabList .nt-ul .is-active + li:before {
  238. display: none;
  239. }
  240.  
  241. .navTabList .nt-ul .is-active i {
  242. width: 14px;
  243. }
  244.  
  245. .navTabList .navTab_right {
  246. position: absolute;
  247. height: 28px;
  248. right: 0;
  249. line-height: normal;
  250. padding: 3px 6px;
  251. background: white;
  252. box-shadow:0 5px 10px #ddd ;
  253. z-index: 2;
  254. }
  255.  
  256. .navTabList .navTab_right .el-button-group {
  257. vertical-align: top;
  258. }
  259.  
  260. .navTabList .el-button--mini {
  261. font-size: 12px;
  262. /*padding: 4px 6px;*/
  263.  
  264. }
  265. </style>

先上代码 可能一脸懵逼 ,接下来我说说我大概的思路:

首先基于element-ui框架el-tabs 组建

然后用watch  来监听路由

当监听到路由变化时和数组中路由列表比较如果有就不做处理,没有的话就新增路由到数组

删除的话就是从路由列表中删除该项

然后样式的话我做了ui上的调整

vue中实现后台管理路由标签页的更多相关文章

  1. 写了一个vue+antdv的后台管理模板

    1,项目简介 写在前面===>这是一个vue+antdv的后台管理模板 项目地址: https://github.com/BaiFangZi/vue-antd-manage 1.1,概述 ​ 最 ...

  2. Vue中使用children实现路由的嵌套

    Vue中使用children实现路由的嵌套 相关Html: <!DOCTYPE html> <html lang="en"> <head> &l ...

  3. vue中使用key管理可复用的元素

    1.概述 Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染. key解决上述问题之外的情景:这两个元素是完全独立的,不要复用它们. 2.示例 <!DOCTYPE html&g ...

  4. vue-route(三)后台管理路由配置

    在一个后台管理的项目中,关于路由的配置,     我们需要实现的一个布局是header,aside,main三部分,后期还可能添加footer部分,实现的需求是请求数据时,局部的刷新,这个时候我们就需 ...

  5. Tabio – 轻松,高效的管理 Chrome 标签页

    Tabio 是一个 Chrome 扩展,旨在简化大量浏览器标签页的管理.它提供的搜索功能允许您快速.轻松地找到您需要的选项卡.Tabio 便于组织你的标签,简单的拖拽排序.您也可以使用输入.删除和箭头 ...

  6. vue+elementui搭建后台管理界面(3侧边栏菜单)

    上一节搭好了主框架,但是标签页和侧边栏只是分别展示了各自的菜单,如何将二者联动起来? 定义路由规则:当有 children 属性时,从 children 里取出 path 填充到侧边栏,如: { pa ...

  7. Django(十八)后台管理:列表页选项、编辑页选项、自定义后台页面

    [参考]https://blog.csdn.net/u010132177/article/details/103814357 [参考]https://docs.djangoproject.com/zh ...

  8. vue中如何不通过路由直接获取url中的参数

    前言:为什么要不通过路由直接获取url中的参数? vue中使用路由的方式设置url参数,但是这种方式必须要在路径中附带参数,而且这个参数是需要在vue的路由中提前设置好的. 相对来说,在某些情况下直接 ...

  9. 在Vue中由后台数据循环生成多选框CheckBox时的注意事项

    多选框是一种非常常见的功能,有时候我们会根据后台返回的数据进行多选框渲染,之前做项目时遇到循环生成多选框时,v-model绑定的值会随着选中与取消改变,但页面却不会变化 的情况,后来测试了一下,发现多 ...

随机推荐

  1. JS 移动端轮播图案例

    body { margin:; } .hearder { width: 100%; height: 150px; position: relative; } ul { list-style: none ...

  2. 7、Java 循环结构

    本章讲解一下Java中常见的三种循环结构,顺序结构的程序语句只能 被执行一次.使用循环可以解决我们多个常量或者变量的同一类的操作或者更加复杂的操作. 循环 循环结构有三大类: 1.for循环:确定循环 ...

  3. SonarQube 跳过指定检查

    SonarQube 跳过指定检查 如何让 SonarQube 忽略某些检查规则 环境 演示环境参考前边的文章 SonarQube 扫描 Java 代码 步骤 我们已经扫描一个 Java 项目 有 6 ...

  4. SPP、ASPP、RFB、CBAM

    SPP:ASPP:将pooling 改为了 空洞卷积RFB:不同大小的卷积核和空洞卷积进行组合,认为大的卷积应该有更大的感受野. CBAM:空间和通道的注意力机制 SPP: Spatial Pyram ...

  5. flask-migrate 处理sqlite数据库报错Constraint must have a name 的解决方案

    环境:flask+python+sqlite,我想给某个表里某个字段加unique属性 执行 python manage.py db migrate 没报错,执行 python manage.py d ...

  6. 【WC2013】 糖果公园 - 树上莫队

    问题描述 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩.糖果公园的结构十分奇特,它由 n 个游览点构成, ...

  7. java Semaphore实现ABC三个线程循环打印

    Semaphore位于java.util.concurrent包下.其中有两个重要的方法acquire()和release().acquire用来获取一个信号量,并且是阻塞型的,如果当前还有可用的信号 ...

  8. Spring @Transactional事物配置无效原因

    spring @transaction不起作用,Spring事物注意事项 1. 在需要事务管理的地方加@Transactional 注解.@Transactional 注解可以被应用于接口定义和接口方 ...

  9. 用Python的Pandas和Matplotlib绘制股票唐奇安通道,布林带通道和鳄鱼组线

    我最近出了一本书,<基于股票大数据分析的Python入门实战 视频教学版>,京东链接:https://item.jd.com/69241653952.html,在其中给出了MACD,KDJ ...

  10. SpringCloudAlibaba-服务网关Gateway

    一:网关简介 在微服务架构中,一个系统会被拆分为很多个微服务.那么作为客户端要如何去调用这么多的微服务呢?如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去调用.这样的话会产生很多问 ...