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绑定的值会随着选中与取消改变,但页面却不会变化 的情况,后来测试了一下,发现多 ...
随机推荐
- WebMvcConfigurerAdapter在2.x向上过时问题
在spring boot2.x向上,书写配置类时集成的WebMvcConfigurerAdapter会显示此类已经过时. 解决:不继承WebMvcConfigurerAdapter类,该实现WebMv ...
- CentOS7安装MinIO教程,并在C#客户端WPF中实现监控上传进度
MinIO的详细介绍可以参考官网(https://min.io/product/overview). 简单来说它是一个实现了AWS S3标准的100%开源的,可商用的( Apache V2 licen ...
- Netty(二):如何处理io请求?
文接上一篇.上篇讲到netty暴露一个端口出来,acceptor, handler, pipeline, eventloop 都已准备好.但是并没体现其如何处理接入新的网络请求,今天我们就一起来看看吧 ...
- homekit_四路继电器
这款继电器使用苹果手机进行控制,有普通版本和点动版本可供选择,有兴趣的可以去以下链接购买: https://item.taobao.com/item.htm?spm=a1z10.1-c.w4004-1 ...
- 简述python中`functools.wrapper()
简述python中functools.wrapper() 首先对于最简单的函数: def a(): pass if __name__ == '__main__': print(a.__name__) ...
- python去除 数据的 重复行
原文链接:https://www.cnblogs.com/loren880898/p/11303672.html
- (趣味哈哈镜)JMF中摄像头相关的问题
JMF已经非常古老了.最近由于做实验的需要,不得不使用JMF处理视频.开发使用win10系统和eclipse.使用中的问题如下: 1.首先想要使用JMF需要必须安装32位JDK,同时编译软件也需要是3 ...
- C++ Templates(1.3 多模板参数 Multiple Template Parameters)
返回完整目录 目录 1.3 多模板参数 Multiple Template Parameters 1.3.1 为返回类型设置模板参数参数 Template Parameters for Return ...
- Linux环境安装Docker入门教程
安装 下载 wget https://download.docker.com/linux/static/stable/x86_64/docker-18.06.1-ce.tgz 解压 tar -xvf ...
- 给你的Swagger文档换套附魔皮肤吧
前言 相信无论是前端或是后端的程序员对Swagger都不怎么陌生,没有用过应该也听说过 Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务. 简 ...