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绑定的值会随着选中与取消改变,但页面却不会变化 的情况,后来测试了一下,发现多 ...
随机推荐
- VMWare虚拟机问题总结
windows7提示:在该系统上全局禁用了虚拟打印功能,不会为该虚拟机启用此功能,虚拟设备:'seria10'将断开连接. 解决:打开虚拟机前选择 编辑-->首选项-->设备--&g ...
- 【JavaScript】windows.open用法详解
windows.open("URL","窗口名称","窗口外观设定");的用法详解 function onNewWindows(redire ...
- 2020-06-11:Redis支持的数据类型?
福哥答案2020-06-11: 福哥口诀法:字哈列集有(string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合))位超地流(位图bitma ...
- 2020-04-29:现在你有个秒杀抢购的app,用户不断大量增加,技术层面,你要怎么做
2020-04-29:现在你有个秒杀抢购的app,用户不断大量增加,技术层面,你要怎么做,才能既满足用户需求,又能扛住压力,还能帮公司合理支出?福哥答案2020-04-29: 限流(杀部分用户祭天). ...
- noip复习——快速幂
\(a ^ n \bmod p\) \(a, p, n \leq 10^9\) 最普通的二进制拆分 #define LL long long LL qpow(LL a, LL n, LL p) { L ...
- 【AHOI 2015】 小岛 - 最短路
描述 西伯利亚北部的寒地,坐落着由 N 个小岛组成的岛屿群,我们把这些小岛依次编号为 1 到 N . 起初,岛屿之间没有任何的航线.后来随着交通的发展,逐渐出现了一些连通两座小岛的航线.例如增加一条在 ...
- 【服务器部署】Django+宝塔+Nginx_uwsgi部署
:CentOS安装脚本: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install ...
- RPC 框架 Dubbo 从理解到使用(一)
技术架构演变 单一应用架构 通俗地讲,"单体应用(monolith application)"就是将应用程序的所有功能都打包成一个独立的单元.当网站流量很小时,只需一个应用,将所有 ...
- 笔记:html基础
一.HTML:超文本标记语言,是一种标签语言,不是编程语言,显示数据有双标签<body></body> 和单标签<img src=# / >, 标签大小写都可以 通 ...
- javaString详解
String基础 Java String 类 字符串广泛应用 在 Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串. 创建字符串 创建字符串最简单 ...