这是一套基于 vue
和 element-ui
, 实现了 tab-router
(一个基于 tab 的路由) 的 单页面, 多页签 应用程序。
我之前写这个项目的时候,有写了一篇 记一次基于vue的spa多页签实践经验
然后就部分热心网友就在下面回复了一些其他类似的项目,我逐一查看了一下,发现基本都是基于 vue-router
和 keep-alive
实现的,这种实现方法有两个比较明显的问题,第一是很难在页签内部跳转,比如我现在这个页签打开的是组件a,然后点击组件a里面的某个链接,我想跳转到组件b,但是是需要在页签不变的情况下打开,不能在新的页签打开,这样基于路由的就很难实现。
另一个问题就是 需要处理 keep-alive
的问题,有趟过 keep-alive
的坑的童鞋基本都了解。
那么我这个 vue-multi-tab
跟其他产品有什么不同呢?--除了实现多页签功能以为,我们还有很多跟其他同类产品不同的特性,如下。
https://noahlam.github.io/vue-multi-tab/
脚手架安装
1.$: sudo npm i tab-cli -g
2.$: tab-cli 根据提示输入项目名称
手动克隆
1.$: git clone https://github.com/noahlam/vue-multi-tab.git
2.$: cd vue-multi-tab && npm i
项目结构
开发的代码全部在 src 里面, src 以外的都是一些配置文件,如果你不需要配置,请直接关注 src 即可
src/MainFrame 框架页内容
src/Images 静态图片文件
src/Router 路由配置, 路由表为 TabRouter.js
src/Store Vuex 目录
src/Styles 一些全局的公共样式
src/Views 实际页面存放位置, 建议业务组件都放这里
keep-alive
问题vue-router
的 API(push,replace,back)tips: 所有的 API 都是放在 this.$tab 对象下面,如 this.$tab.open(...)
open 打开一个页签
如果当前页签未打开过,则打开一个新的页签,如果页签已存在,则跳转到当前页签.
接收一个对象做参数,格式如下:
{
title: '子菜单1-2',
component: 'index',
menuId: '1-2'
}
这个格式,其实就是菜单配置(见 src/Frame/MainConf.js)里的格式,这么设计,是方便直接在菜单列表上打开当前菜单
<el-menu-item-group>
<el-menu-item v-for="(item,index) in menuList"
:key="index"
@click="$tab.open(item)"
:index="item.menuId">
{{item.title}}
</el-menu-item>
</el-menu-item-group>
tips: menuId 可以自己随意定义,但是要不重复, component 是组件的
路由名称
(暂且这么称呼吧,其实就是类似 vue-router 的 path), 组件的路由表在src/Router/TabRoute.js
里
close 关闭一个页签
接收一个 menuId 作为参数,对应要关闭的 tab 的 menuId.如果 menuId 没传,或者传的 menuId 在打开的 tab 列表里面没找到对应的.则不做任何操作.
showTab 切换 tab
接收一个 menuId 作为参数,对应要激活的 tab 的 menuId.如果menuId没传,或者传的 menuId 在打开的 tab 列表里面没找到对应的.则会不激活任何页签.
push 标签内跳转
类似 vue 的 this.$router.push,可以在当前页签下跳转到另一个组件,且可以带参数
第一个参数【必选】 可以是字符串,也可以是对象 1.String 1.1 字符串不带参数,就是一个组件名。打开对应的组件 1.2 字符串后带查询参数,会自动解析,并在目标组件可以通过 this.$tab.query() 获取,需要注意的是 query() 是一个函数,这个跟 vue-router 不同,不过返回的数据格式跟 this.$route.query 一样
2.Object 第一个参数是一个对象的话,格式如下
{
path:'组件名称', // 必选
query: {} // 可选,Object类型,要带的查询参数,获取方式同上
}
第二个参数【可选】,是一个对象 也是查询参数,这个参数会上面参数合并,如果刚好有同名的参数,则会覆盖上面的参数 理论上,push()方法是可以在全局的任何地方使用,不过需要注意的是不管何时,在哪里push,push的目标始终是当前激活的那个tab.
》tips: 这个方法完全就是模仿 vue-router 的 this.$router.push, 不过只是浅层次的模仿。
replace 标签内替换组件
用法同 push,不同的是 replace 是直接替换当前历史记录,所以不会产生新的历史记录
back 标签内后退
接收一个正整数作为后退的步数(可选,默认是1)
closeAll 关闭所有标签
关闭所有打开的标签,除了首页外(目前的首页 MainConf.homeTab
配置是不能关闭的,如果你想首页能关闭,请配置成普通菜单)
closeOthers 关闭除当前标签外的所有标签
接收一个 menuId 作为参数,除了跟这个 menuId 相匹配的 tab 不关,其他的 tab 全部关掉(首页依然是那么顽皮,关不掉,同上)
reShow 根据地址栏数据,回显标签和标签内的组件
根据浏览器地址,回显当前 tab, 回显内容包括 1. 打开 tab, 2.得到上次的历史记录 3.打开 tab 里上次显示的组件 4.如果调用this.$tab.back() 方法,可以基于上次的历史记录返回。
query 获取 push,replace 传递的参数
类似 this.$route.query, query() 返回的也是一个对象。不过唯一点不同的是 我们这里的 query() 是一个函数,所以你应该在后面给他一对括号
let id = this.$tab.query().id
info 获取 当前激活的 tab 对象
返回 当前激活的 tab 对象, 也是一个函数, 要这样调用 this.$tab.info()
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。