vue中实现后台管理路由标签页
<template>
<section>
<div class="navTabList el-tabs__nav-scroll" id="tabsNav" v-if="showTags">
<ul class="nt-ul el-tabs__nav" id="tabsNavList">
<li v-for="(item,index) in tagsList" :class="{'is-active': isActive(item.path)}" :key="index">
<router-link :to="item.path" class="tags-li-title">
{{item.title}}
</router-link>
<i class="el-tag__close el-icon-close" @click="closeTags(index)"></i></li>
</ul>
<div class="pull-right navTab_right">
<el-button-group>
<el-button size="mini" icon="el-icon-arrow-left" @click="tabsPrev()"></el-button>
<el-button size="mini" icon="el-icon-arrow-right" @click="tabsNext()"></el-button>
</el-button-group>
<el-dropdown @command="handleTags">
<el-button size="mini" type="primary">
标签选项
<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="other">关闭其他页面</el-dropdown-item>
<el-dropdown-item command="all">关闭所有页面</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</section>
</template> <script>
import bus from './bus' export default {
data() {
return {
tagsList: [],
counter: '0'
}
},
methods: {
tabsNext() {
let tabNav = document.getElementById('tabsNav')
let tabNavList = document.getElementById('tabsNavList')
let tabNavW = tabNav.clientWidth
let tabNavListW = tabNavList.clientWidth
if (tabNavW < tabNavListW && this.counter + tabNavW - 210 < tabNavListW) {
this.counter = parseInt(this.counter) + parseInt(tabNavW) - 210
tabNavList.style.transform = 'translateX(' + '-' + this.counter + 'px)'
} else {
}
},
tabsPrev() {
let tabNav = document.getElementById('tabsNav')
let tabNavList = document.getElementById('tabsNavList')
let tabNavW = tabNav.clientWidth if (tabNavW <= this.counter + tabNavW - 210) {
this.counter = parseInt(this.counter) - parseInt(tabNavW) + 210
tabNavList.style.transform = 'translateX(' + '-' + this.counter + 'px)'
} else if (this.counter !== 0) {
this.counter = 0
tabNavList.style.transform = 'translateX(' + '0' + 'px)'
} else {
}
},
isActive(path) {
return path === this.$route.fullPath
},
// 关闭单个标签
closeTags(index) {
const delItem = this.tagsList.splice(index, 1)[0]
const item = this.tagsList[index] ? this.tagsList[index] : this.tagsList[index - 1]
if (item) {
delItem.path === this.$route.fullPath && this.$router.push(item.path)
} else {
this.$router.push('/dashboard')
}
},
// 关闭全部标签
closeAll() {
this.tagsList = []
this.$router.push('/dashboard')
},
// 关闭其他标签
closeOther() {
const curItem = this.tagsList.filter(item => {
return item.path === this.$route.fullPath
})
this.tagsList = curItem
},
// 设置标签
setTags(route) {
const isExist = this.tagsList.some(item => {
return item.path === route.fullPath
})
if (!isExist) {
if (this.tagsList.length >= 99) {
this.tagsList.shift()
}
this.tagsList.unshift({
title: route.meta.title,
path: route.fullPath,
name: route.matched[1].components.default.name
})
}
// bus.$emit('tags', this.tagsList)
},
handleTags(command) {
command === 'other' ? this.closeOther() : this.closeAll()
}
},
computed: {
showTags() {
return this.tagsList.length > 0
}
},
watch: {
$route(newValue, oldValue) {
this.setTags(newValue)
}
},
created() {
this.setTags(this.$route)
// 监听关闭当前页面的标签页
bus.$on('close_current_tags', () => {
for (let i = 0, len = this.tagsList.length; i < len; i++) {
const item = this.tagsList[i]
if (item.path === this.$route.fullPath) {
if (i < len - 1) {
this.$router.push(this.tagsList[i + 1].path)
} else if (i > 0) {
this.$router.push(this.tagsList[i - 1].path)
} else {
this.$router.push('/dashboard')
}
this.tagsList.splice(i, 1)
}
}
})
}
}
</script> <style scoped>
.navTabList {
padding-right: 210px;
height: 34px;
line-height: 34px;
background: #f4f4f4;
margin-bottom: 10px;
font-size: 12px;
background-color: white;
box-shadow:0 5px 10px #ddd ;
} .navTabList .nt-ul {
float: left;
margin: 0;
padding: 0;
list-style: none;
} .navTabList .nt-ul li {
display: inline-block;
margin: 1px 5px 2px 1px;
border-radius: 3px;
font-size: 12px;
overflow: hidden;
cursor: pointer;
height: 24px;
line-height: 24px;
border: 1px solid #e9eaec;
background: #fff;
padding: 2px 12px 0 12px;
vertical-align: middle;
color: #666;
-webkit-transition: all 0.3s ease-in;
-moz-transition: all 0.3s ease-in;
transition: all 0.3s ease-in;
} .navTabList .nt-ul li:before {
content: '';
width: 1px;
height: 23px;
position: absolute;
left: 0;
top: 7px;
border-right: 1px solid #e4e4e4;
} .navTabList .nt-ul li:first-child:before {
display: none;
} .navTabList .nt-ul li i {
position: relative;
font-size: 12px;
width: 0;
height: 14px;
vertical-align: middle;
line-height: 15px;
overflow: hidden;
top: -1px;
right: -10px;
} .navTabList .nt-ul li i {
width: 14px;
} .navTabList .nt-ul li a {
display: inline-block;
color: #999;
} .navTabList .nt-ul .is-active {
padding: 0 13px;
/*margin-top: 2px;*/
height: 30px;
line-height: 30px;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
background: #409eff;
font-weight: bold;
color: white;
}
.navTabList .nt-ul .is-active a{
color: white;
} .navTabList .nt-ul .is-active:before {
display: none;
} .navTabList .nt-ul .is-active + li:before {
display: none;
} .navTabList .nt-ul .is-active i {
width: 14px;
} .navTabList .navTab_right {
position: absolute;
height: 28px;
right: 0;
line-height: normal;
padding: 3px 6px;
background: white;
box-shadow:0 5px 10px #ddd ;
z-index: 2;
} .navTabList .navTab_right .el-button-group {
vertical-align: top;
} .navTabList .el-button--mini {
font-size: 12px;
/*padding: 4px 6px;*/ }
</style>
先上代码 可能一脸懵逼 ,接下来我说说我大概的思路:
首先基于element-ui框架el-tabs 组建
然后用watch 来监听路由
当监听到路由变化时和数组中路由列表比较如果有就不做处理,没有的话就新增路由到数组
删除的话就是从路由列表中删除该项
然后样式的话我做了ui上的调整
vue中实现后台管理路由标签页的更多相关文章
- 写了一个vue+antdv的后台管理模板
1,项目简介 写在前面===>这是一个vue+antdv的后台管理模板 项目地址: https://github.com/BaiFangZi/vue-antd-manage 1.1,概述 最 ...
- Vue中使用children实现路由的嵌套
Vue中使用children实现路由的嵌套 相关Html: <!DOCTYPE html> <html lang="en"> <head> &l ...
- vue中使用key管理可复用的元素
1.概述 Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染. key解决上述问题之外的情景:这两个元素是完全独立的,不要复用它们. 2.示例 <!DOCTYPE html&g ...
- vue-route(三)后台管理路由配置
在一个后台管理的项目中,关于路由的配置, 我们需要实现的一个布局是header,aside,main三部分,后期还可能添加footer部分,实现的需求是请求数据时,局部的刷新,这个时候我们就需 ...
- Tabio – 轻松,高效的管理 Chrome 标签页
Tabio 是一个 Chrome 扩展,旨在简化大量浏览器标签页的管理.它提供的搜索功能允许您快速.轻松地找到您需要的选项卡.Tabio 便于组织你的标签,简单的拖拽排序.您也可以使用输入.删除和箭头 ...
- vue+elementui搭建后台管理界面(3侧边栏菜单)
上一节搭好了主框架,但是标签页和侧边栏只是分别展示了各自的菜单,如何将二者联动起来? 定义路由规则:当有 children 属性时,从 children 里取出 path 填充到侧边栏,如: { pa ...
- Django(十八)后台管理:列表页选项、编辑页选项、自定义后台页面
[参考]https://blog.csdn.net/u010132177/article/details/103814357 [参考]https://docs.djangoproject.com/zh ...
- vue中如何不通过路由直接获取url中的参数
前言:为什么要不通过路由直接获取url中的参数? vue中使用路由的方式设置url参数,但是这种方式必须要在路径中附带参数,而且这个参数是需要在vue的路由中提前设置好的. 相对来说,在某些情况下直接 ...
- 在Vue中由后台数据循环生成多选框CheckBox时的注意事项
多选框是一种非常常见的功能,有时候我们会根据后台返回的数据进行多选框渲染,之前做项目时遇到循环生成多选框时,v-model绑定的值会随着选中与取消改变,但页面却不会变化 的情况,后来测试了一下,发现多 ...
随机推荐
- 朴素贝叶斯分类器基本代码 && n折交叉优化 2
这个代码基于上一个代码 不同的是:读取了txt文件,改变了min_ft与max_ft的参数 import re import pandas as pd import warnings import n ...
- 重写ThreadPoolTaskExecutor
目录 主类开启异步注解 创建线程池配置类 创建线程池实现类 创建一个测试类Controller 创建异步Service方法 定义异步的实现类 ThreadPoolExecutor:JDK内置线程池实现 ...
- Canal v1.1.4版本避坑指南
前提 在忍耐了很久之后,忍不住爆发了,在掘金发了条沸点(下班时发的): 这是一个令人悲伤的故事,这条情感爆发的沸点好像被屏蔽了,另外小水渠(Canal意为水道.管道)上线一段时间,不出坑的时候风平浪静 ...
- java基础之字符串
以下内容摘自<java编程思想>第十三章. 1. 不可变 String String 对象是不可变对象,String 类中每一个看起来会修改 String 值的方法,实际上都是创建了一个全 ...
- C++中简单程序出现Segmentation fault (core dumped)段错误
段错误就是指访问的内存超出了系统所给这个程序的内存空间.一般是随意使用野指针或者数组.数组越界. ------两种简单解决方法:1.利用GDB调试,定位出错位置.(具体可查找博客详细学习)2.在可能出 ...
- C#LeetCode刷题之#645-错误的集合(Set Mismatch)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3887 访问. 集合 S 包含从1到 n 的整数.不幸的是,因为数 ...
- Vue element-ui el-table阻止行选事件
我们经常会在某个table末尾加上操作列来放置button来处理跳转和其他的逻辑 那么当点击button的时候同样也会执行在el-table 设置的 @row-click="handleRo ...
- Java 创建、刷新Excel透视表/设置透视表行折叠、展开
透视表是依据已有数据源来创建的交互式表格,我们可在excel中创建透视表,也可编辑已有透视表.本文以创建透视表.刷新透视表以及设置透视表的行展开或折叠为例,介绍具体的操作方法. 所需工具:Free S ...
- 一、Spring的基本应用
1.spring导包 导入maven包 <dependencies> <dependency> <groupId>org.springframework</g ...
- 炼技术(9): 简约而不简单,永不停歇的测试 -- always_run
最强战力,永不停歇的测试:always_run 许多工程师写完程序后,都不愿意对自己的程序做仔细测试. 很多测试说会做自动化测试,可能工作好几年都没真做过多少自动化测试. 我们的解决方案是,在系统的测 ...