vue 后台系统中多页面标签

article/2025/11/4 22:06:13

        在后台开发中,常用一种页面标签工具,每次点击菜单栏时,会在页面区域上方增加一个【标签页】如下图,可关闭,可切换页面等功能,常见于后台管理系统中。

        以前,我以为这个是利用tabs组件开发的,但是后来看了一些文章才发现,它实际上跟tabs组件没有任何关系(当然你可以用tabs做,实现过程不限于任何技术)

原理:

1 点击菜单栏时,将【菜单项】数据记录在vuex中,或者你存本地的storage中,怎么做都行,但你得保存下来

2 上方标签,通过读取我的路由链,然后用ant vue 【tag】标签渲染(当然你可以用自己方式做)

3 关闭,点击关闭后,要删除路由链,并且要做跳转,当然这里要做判断,如果关闭当前页,则往后面的跳,如果是最后一项,则跳转至开头第一项(路由链中,首页默认设置第一项)

目前,我只简单说到以上的功能,至于其它功能,你可以自己加。

实现:只做实现,质量暂时先不看中

1 vuex中设置路由链,打开你的store/index.js

 

import Vue from 'vue'
import router from '@/router'
import Vuex from 'vuex'
Vue.use(Vuex)export default new Vuex.Store({state: {tagsRouter: [],},getters: {getTagsRouter(state) {//获取标签路由信息return state.tagsRouter},},mutations: {setRouterTagActive(state, routeItem) {//设置当前的tag页为活动页for (let i = 0; i < state.tagsRouter.length; i++) {let item = state.tagsRouter[i]state.tagsRouter[i].isActive = falseif (state.tagsRouter[i].name === routeItem.name) {state.tagsRouter[i].isActive = true}}console.log(state.tagsRouter)},addRoute(state, routeItem) {//选择菜单后,添加至本地路由信息中let flog = falsefor (let i = 0; i < state.tagsRouter.length; i++) {let item = state.tagsRouter[i]if (state.tagsRouter[i].name === routeItem.name) {flog = truebreak}}if (!flog) {state.tagsRouter.push({path: routeItem.path,name: routeItem.name,meta: routeItem.meta,})}},delRoute(state, params) {//删除tags路由项if (state.tagsRouter.length != 0) {let itemIndex = 0for (let i = 0; i < state.tagsRouter.length; i++) {let item = state.tagsRouter[i]if (state.tagsRouter[i].meta.menuKey === params.item.meta.menuKey) {//itemIndex = istate.tagsRouter.splice(i, 1)break}}//跳除后的跳转}},},actions: {doSomething(context, val) {//应用:this.$store.dispatch("doSomething",{})//提交mutations内的方法:context.commit("setUser",val)},},modules: {},
})

2 设置下路由信息,打开router/index.js

路由信息可跟据你的来,我只是截取了一下自己的实验内容,meta中可添加自己的信息

import Vue from 'vue'
import VueRouter from 'vue-router'import store from '@/store/index'
Vue.use(VueRouter)// 页面跳转时的进度条
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'NProgress.configure({easing: 'ease', // 动画方式speed: 500, // 递增进度条的速度showSpinner: false, // 是否显示加载icontrickleSpeed: 200, // 自动递增间隔minimum: 0.3, // 初始化时的最小百分比
})// routes设置根据你的项目来即可,我截取了一部分,可能会有错
const routes = [{path: '/',name: 'index',meta: { title: '首页', icon: 'home', menuKey: '1', menu: true },redirect: '/Dashboard/DashboardIndex',component: () =>import(/* webpackChunkName: "about" */ '../views/HomeView.vue'),},{path: '/Dashboard',name: 'Dashboard',meta: { title: 'Dashboard', icon: 'bar-chart', menuKey: '2' },component: () => import('../views/HomeView.vue'),children: [{path: 'DashboardIndex',name: 'DashboardIndex',meta: { title: 'DashboardIndex', icon: '', menuKey: '2.1' },component: () => import('@/views/dashboard/Dashboard.vue'),},],},{path: '/block',name: 'block',meta: { title: '链基础网络', icon: 'apartment', menuKey: '3' },component: () => import('../views/HomeView.vue'),children: [{path: 'BlockChainSetting',name: 'BlockChainSetting',meta: { title: '链配置', icon: '', menuKey: '3.1' },component: () => import('@/views/blockchain/BlockChainSetting.vue'),},{path: 'BlockChainSetUp',name: 'BlockChainSetUp',meta: { title: '链搭建', icon: '', menuKey: '3.2' },component: () => import('@/views/blockchain/BlockChainSetUp.vue'),},{path: 'BlockChainNetInfo',name: 'BlockChainNetInfo',meta: { title: '网络状态', icon: '', menuKey: '3.3' },component: () => import('@/views/blockchain/BlockChainNetInfo.vue'),},],}
]//NProgress 该组件是页面跳转时,页面上方出现的一条进度条,要安装下,npm install --save nprogressconst router = new VueRouter({mode: 'hash',base: process.env.BASE_URL,routes,
})router.beforeEach((to, from, next) => {// 每次切换页面时,调用进度条NProgress.start()if (to.meta.menuKey != undefined) {store.commit('addRoute', to)store.commit('setRouterTagActive', to)}next()
})//当路由进入后:关闭进度条
router.afterEach(() => {// 在即将进入新的页面组件前,关闭掉进度条NProgress.done()
})export default router

3 开发tags组件

<template><div class="menu-tags"><a-tag:class="['menu-tags_item', item.isActive ? 'item_active' : '']"closablev-for="(item, index) in data":key="item.name + index"@close="handleClose(item)"@click="handleSelect(item)"><span :class="item.isActive ? 'item_active' : ''">{{item.meta.title}}</span></a-tag></div>
</template><script>
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'export default {name: 'MenuTags',props: {},data() {return {data: [],}},computed: {...mapState({tagData() {return this.$store.state.tagsRouter},}),...mapGetters({getTagsRouterData: 'getTagsRouter', // 获取标签路由信息}),},// 定义引入的组件components: {},//变量监听watch: {},// 页面初始化created() {},// 页面DOM加载完成mounted() {let _this = this_this.init()},//离开页面时执行destroyed() {},watch: {},// 页面方法methods: {...mapMutations({mySetRouterTagActive: 'setRouterTagActive', // clickTotal 是mutation 里的方法,totalAlise是重新定义的一个别名方法,本组件直接调用这个方法}),init() {let _this = this_this.$set(_this, 'data', [])_this.$nextTick(() => {_this.$set(_this, 'data', _this.$store.state.tagsRouter)})},handleClose(item) {let _this = this//item.isActive = truelet tempData = [..._this.data]_this.$store.commit('delRoute', {item,isSameRoute: _this.$route.path == item.path,})if (tempData.length != 0 && _this.$route.path == item.path) {//跳转let gotoPath = ''for (let i = 0; i < tempData.length; i++) {if (tempData[i].path == item.path) {if (tempData[i + 1] != undefined) {gotoPath = tempData[i + 1].path} else if (tempData.length != 0) {gotoPath = tempData[0].path}break}}if (gotoPath != '') {_this.handleGoto(gotoPath)}}},handleSelect(item) {let _this = this//如果是当前页,则不跳if (item.name != _this.$route.name) {_this.$router.push({path: item.path,})_this.mySetRouterTagActive(item)_this.$nextTick(() => {_this.init()})}},handleGoto(path) {let _this = thisif (_this.$common.isNull(path)) {return false}_this.$router.push({path: path,})},},
}
</script><style lang="less" scoped>
.menu-tags {margin-left: 16px;.menu-tags_item {padding: 2px 10px;cursor: pointer;}.menu-tags_item:hover {color: #63d5ce;}.item_active {color: #63d5ce;}
}
</style>

 4 引入到你的页面中,具体我不写了,你自己引

5 结果

 其实,这个组件稍微有点麻烦,但原理就是,你如何处理每次点击的菜单项,把它存在哪,然后再渲染出来就行了。

 


http://chatgpt.dhexx.cn/article/3R0ZRTZx.shtml

相关文章

js关闭浏览器页签

兼容性 js实现 function closeWebPage(){if (navigator.userAgent.indexOf("MSIE") > 0) {if (navigator.userAgent.indexOf("MSIE 6.0") > 0) {window.opener null;window.close();}else {window.open(, _top);window.top.close();}}else if (nav…

layui————一个页面展示两个页签

html页面 <!DOCTYPE html> <html> <head><meta charset"utf-8"><link rel"stylesheet" href"../../../build/css/base.css" media"all"> </head> <body> <div class"layui-tab la…

SAP BP屏幕增强页签

导语&#xff1a;最近收到了BP的需求&#xff0c;要增加页签&#xff0c;找了一些资料&#xff0c;发现BP的增强页签可是真麻烦啊&#xff0c;下面把我梳理出来的分享一下。 &#x1f449;【增强记录清单…】 需求&#xff1a; 需求是在供应商界面增加一个页签&#xff0c;用…

修改浏览器页签名称

第一种若是整个系统要统一修改为一个名称 在public文件夹下index.html下直接修改或者在相应配置文件package.json或者其他&#xff08;看项目配置&#xff09; 第二种某一个路由或者菜单页签不一样的名称 可以配置到后置路由中或者组件内 语句为:document.title 测试

vue实现tagsview多页签导航功能

文章目录 前言一、效果图二、实现思路1. 新建 tags-view.js2. 在Vuex里面引入 tags-view.js3. 新建 tabsView 组件4. 新建 ScrollPane 组件5. 引入 tabsView 组件6. 使用 keep-alive 组件&#xff0c;进行页签的缓存 总结 前言 基本上后台管理系统都需要有多页签的功能&#x…

基于微前端qiankun的多页签缓存方案实践

作者&#xff1a;vivo 互联网前端团队- Tang Xiao 本文梳理了基于阿里开源微前端框架qiankun&#xff0c;实现多页签及子应用缓存的方案&#xff0c;同时还类比了多个不同方案之间的区别及优劣势&#xff0c;为使用微前端进行多页签开发的同学&#xff0c;提供一些参考。 一、…

Sublime Text的命令行工具subl

在sublime的安装目录下有个subl.exe&#xff0c;是sublime编辑器为用户提供的命令行工具。 修改Windows系统的环境变量&#xff0c;将sublime的安装路径添加到环境变量里&#xff1b; 打开win的命令行提示符程序&#xff0c;输入subl -version,看到结果如下图所示&#xff1a;…

Macbook Pro下安装subl命令,快速使用sublime打开代码

一、使用背景 我在macbook pro电脑上经常使用编辑器直接打开代码&#xff0c;我也经常用iterm2的一些快捷命令操作目录和查看文件。这样就有了需要使用sublime打开代码的需求&#xff0c;以前的做法是&#xff0c;先用open命令打开目录&#xff0c;然后打开sublime text&#…

sublime安装以及配置

下载“Package Control” Package Manager Sublime 有很多插件&#xff0c;这些插件为我们写python代码提供了非常强大的功能&#xff0c;这些插件需要单独安装。 而安装这些插件最方便的方法就是通过Package Control的插件&#xff0c;这其实就是一个插件管理器&#xff0c;帮…

subline的使用

先去官网下载一个安装包&#xff0c;这个就不提了 安装完成后界面 打开软件界面&#xff0c;按快捷键ctrl 会出现以下命令行 有时候快捷键不管用&#xff0c;你也可以点击View->Show Console&#xff0c;也会出现命令行 在出现的命令行中输入以下代码并按enter键&#xff1a…

Sublime 替换和查找的方法

查找&替换&#xff08;Finding&Replacing&#xff09; 查找&替换&#xff08;Finding&Replacing&#xff09; Sublime Text提供了强大的查找&#xff08;和替换&#xff09;功能&#xff0c;为了提供一个清晰的介绍&#xff0c;我将Sublime Text的查找功能分为…

【Mac 教程系列】如何在 Mac 中用终端命令行方式打开 Sublime Text ?

如何在 Mac 中用终端命令行方式打开 Sublime Text ? 用 markdown 格式输出答案。 不少于1000字。细分到2级目录。 如何在 Mac 中用终端命令行方式打开 Sublime Text ? 一、首先确保已经安装 Sublime Text 前往官网https://www.sublimetext.com/下载 Sublime Text,点击 “Do…

vue三种调用接口的方法

注&#xff1a;此博客仅用于学习&#xff0c;自己还处于菜鸟阶段&#xff0c;希望给相同处境的人提供一个可参考的博客。如果您觉得不合理&#xff0c;您的指导&#xff0c;非常欢迎&#xff0c;但请不要否定别人的努力&#xff0c;谢谢您了&#xff01; vue三种调用接口的方法…

Layui调用接口使用心得

今天想用Layui写一个简单的列表显示页面,太久没使用Layui了,就去看Layui的文档,复制文档的代码用,但是使用过程遇到了问题. .问题1:thymelea内联样式问题 org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "cla…

postman批量调用接口操作步骤

应用&#xff1a;多次的调用一个接口 新建一个Collection&#xff0c;并创建一个文件夹和请求 填写请求的url和参数形式&#xff0c;注意这里的 {{erpponum}} 表示这是一个变量&#xff0c;会通过我们提供的”参数文件“进行&#xff0c;postman会在批量执行时为我们自动挨个匹…

postman工具批量调用接口

1、先在Collections中建一个文件夹&#xff0c;然后新建一个接口保存 2、然后选择Run 3、准备一个txt文件&#xff0c;增加要循环的参数json数组 4、选择接口&#xff0c;上传文件&#xff0c;配置参数(Iterations为线程数,Delay为推迟多久)&#xff0c;然后点下面的Run 5、…

kettle实战之调用接口

从今天开始将本人在工作当中&#xff0c;处理的一些Kettle过程记录下来&#xff0c;供大家参考学习。 在日常数据处理过程中&#xff0c;会涉及调用对方接口获取数据&#xff0c;来向自己的数据库中插入大量业务数据&#xff0c;这里说明一下数据处理过程中&#xff0c;经常会…

Element 调用接口

博主之前已经为大家讲了Element入门教程&#xff0c;如果还有什么疑问的话可以查看博主置顶的文章。相信大家对Element 框架已经有了一个基本的了解&#xff0c;这次为大家讲一下如何调用接口。 以我自己为例子&#xff0c;我想要调用我接口里的图片&#xff0c;并让他在浏览器…

java接口调用_java 接口怎么调用

一个类实现了某一个接口就可以调用接口中的方法。接口可以理解为一种能力&#xff0c;例如&#xff1a;每种动物都有叫的能力&#xff0c;但是每种动物的叫声都不一样&#xff0c;叫的能力就可以定义为一个接口。 一、创建项目和包 打开Eclipse&#xff0c;依次选择File→New→…

Postman批量调用接口

postman批量调用并不是并发调用 新建个分组 添加对应的调用接口名及参数---千万记住要保存下 添加完之后&#xff0c;点击这里执行 调用次数要和数据条数一致&#xff0c;文件里有10条数据这里就是10&#xff0c;导入完之后这里会自动更新&#xff0c;加入你要是更改为15&…