-
需要运行看效果的访问以下网址
(切换到 tabs-router 分支, vue-userList为前端可以看效果的项目 -- 已关闭接口 -- 直接点登录即可)
:
项目地址
主要代码
- 以下代码储存路由信息时会保留路由携带的参数,点击tabs标签页跳转时会携带原本携带的参数。
- 刷新界面后会默认添加当前页的tabs标签页,不会保留刷新前的存储tabs标签页数据,可根据需求考虑要不要进行浏览器存储以保证刷新后数据还保留。
- 无需下包,无需引入,以下代码都在
菜单配置文件里书写
,标签名取值来自路由文件的title
属性。
- 以下唯一标识是由
路由+路由title名+路由参数id
组成,可根据实际需求更改,但必须保持唯一性。
`路由示例`
// 信息总览
import home from '@/views/home';
export default {
path: '/shopList',
username: 'shopList',
component: home,
children: [
{
path: '',
component: () => import('@/views/shop/index'),meta: { title: '信息总览', icon: 'el-icon-s-promotion' },
},
{
path: '/shopList/shopDetails',
component: () => import('@/views/shop/components/shopDetails.vue'),meta: { title: '详情-信息总览'}
},
],
};
<el-main>
<el-tabs
v-model="editableTabsValue"
type="card"
closable
@tab-click="tabCliclRouter"
@tab-remove="tabRemoveRouter"
>
<el-tab-pane
v-for="item in editableTabs"
:key="`${item.path}-${item.meta.tagNameRouter}-${item.meta.pageId}`"
:label="`${item.meta.tagNameRouter}`"
:name="`${item.path}-${item.meta.tagNameRouter}-${item.meta.pageId}`"
>
{{ item.meta.tagNameRouter }}
</el-tab-pane>
</el-tabs>
<router-view />
</el-main>
data() {
return {
editableTabsValue: "",
editableTabs: [],
};
},
// 侦听器
watch: {
// 监听路由变化
$route: {
handler: function (val, oldVal) {
// 添加tag信息
this.addRouteTags();
},
// 深度观察监听
deep: true,
},
},
mounted() {
// 页面刷新后添加当前路由tabs信息
this.addRouteTags();
},
// 组件方法
methods: {
// 添加路由信息 -- 用于渲染tabs -- 同时添加详情带参数等路由界面信息
addRouteTags() {
const pageId = `${this.$route.query.id ? this.$route.query.id : ""}`;
this.editableTabsValue = `${this.$route.path}-${this.$route.meta.title}-${pageId}`;
// 重复的不添加 -- 匹配路由-名字-id 是否相同
if (
this.editableTabs.find(
(x) =>
`${x.path}-${x.meta.tagNameRouter}-${x.meta.pageId}` ===
`${this.$route.path}-${this.$route.meta.title}-${pageId}`
)
)
return;
// 添加tabs信息
this.editableTabs.push({
path: this.$route.path,
query: this.$route.query,
meta: {
tagNameRouter: this.$route.meta.title,
pageId: pageId,
},
});
},
// tabs标签页点击
tabCliclRouter(val) {
// 匹配正确的路由信息 -- 名字是路由多个唯一参数拼接而成 -- val.name此字段必须确保是唯一的
const pageRouter = this.editableTabs.find(
(x) => `${x.path}-${x.meta.tagNameRouter}-${x.meta.pageId}` === val.name
);
// 跳转tabs存储的对应路由信息,有参数携带参数
this.$router.push({ path: pageRouter.path, query: pageRouter.query });
},
// tabs标签页移除
tabRemoveRouter(val) {
// 删除到第一个时禁止
if (this.editableTabs.length === 1) return;
// 找到对应的要删除tabs数据
const routerFind = this.editableTabs.find(
(x) => `${x.path}-${x.meta.tagNameRouter}-${x.meta.pageId}` === val,
);
// 对要删除的进行去除 -- 找到对应的位置
const indexPath = this.editableTabs.findIndex(
(x) =>
`${x.path}-${x.meta.tagNameRouter}-${x.meta.pageId}` ===
`${routerFind.path}-${routerFind.meta.tagNameRouter}-${routerFind.meta.pageId}`
);
// 根据找到索引进行删除操作
this.editableTabs.splice(indexPath, 1);
// 如果删除的是当前高亮的进行特殊处理 -- 使其高亮到前一个上,并跳转到高亮区域的界面
if (
`${routerFind.path}-${routerFind.meta.tagNameRouter}-${routerFind.meta.pageId}` ===
val
) {
// 改变高亮当前绑定值
this.editableTabsValue = `${
this.editableTabs[this.editableTabs.length - 1].path
}-${
this.editableTabs[this.editableTabs.length - 1].meta.tagNameRouter
}`;
// 跳转到当前高亮区域页面
this.$router.push({
path: this.editableTabs[this.editableTabs.length - 1].path,
query: this.editableTabs[this.editableTabs.length - 1].query,
});
}
},
},
<style scoped lang="less">
::v-deep .el-tabs {
height: 33px;
border-bottom: 1px solid #e5e7ed;
padding-left: 12px;
.el-tabs__item {
color: #000;
height: 30px;
line-height: 30px;
padding: 0 12px;
border: 1px solid #e5e7ed;
margin-right: 8px;
}
.el-tabs__item.is-active {
color: #00ab7a;
background-color: #adebd9;
opacity: 1;
}
.el-tabs__content {
display: none;
}
.el-tabs__item:first-child {
border-left: 1px solid #e5e7ed;
}
.el-tabs__nav {
border: 0px;
}
.el-tabs__nav-scroll {
background: #fff;
}
.el-tabs__nav-prev {
line-height: 30px;
.el-icon-arrow-left {
font-weight: 700;
color: #000;
}
}
.el-tabs__nav-next {
line-height: 30px;
.el-icon-arrow-right {
font-weight: 700;
color: #000;
}
}
}
</style>