antd vue pro (vue 2.x) 多页签详细操作

antd vue pro 多页签配置操作,具体操作如下。

1.引入 tagviews文件

  在 store/modules 中创建 tagviews.js ,复制一下代码到文件中保存

const state = {visitedViews: [],cachedViews: []
}const mutations = {ADD_VISITED_VIEW: (state, view) => {if (state.visitedViews.some(v => v.path === view.path)) returnstate.visitedViews.push(Object.assign({}, view, {title: view.meta.title || 'no-name'}))},ADD_CACHED_VIEW: (state, view) => {if (state.cachedViews.includes(view.name)) returnif (view.meta && view.meta.isCache) {state.cachedViews.push(view.name)}},DEL_VISITED_VIEW: (state, view) => {for (const [i, v] of state.visitedViews.entries()) {if (v.path === view.path) {state.visitedViews.splice(i, 1)break}}},DEL_CACHED_VIEW: (state, view) => {const index = state.cachedViews.indexOf(view.name)index > -1 && state.cachedViews.splice(index, 1)},DEL_OTHERS_VISITED_VIEWS: (state, view) => {state.visitedViews = state.visitedViews.filter(v => {return v.meta.affix || v.path === view.path})},DEL_OTHERS_CACHED_VIEWS: (state, view) => {const index = state.cachedViews.indexOf(view.name)if (index > -1) {state.cachedViews = state.cachedViews.slice(index, index + 1)} else {state.cachedViews = []}},DEL_ALL_VISITED_VIEWS: state => {// keep affix tagsconst affixTags = state.visitedViews.filter(tag => tag.meta.affix)state.visitedViews = affixTags},DEL_ALL_CACHED_VIEWS: state => {state.cachedViews = []},UPDATE_VISITED_VIEW: (state, view) => {for (let v of state.visitedViews) {if (v.path === view.path) {v = Object.assign(v, view)break}}},DEL_RIGHT_VIEWS: (state, view) => {const index = state.visitedViews.findIndex(v => v.path === view.path)if (index === -1) {return}state.visitedViews = state.visitedViews.filter((item, idx) => {if (idx <= index || (item.meta && item.meta.affix)) {return true}const i = state.cachedViews.indexOf(item.name)if (i > -1) {state.cachedViews.splice(i, 1)}return false})},DEL_LEFT_VIEWS: (state, view) => {const index = state.visitedViews.findIndex(v => v.path === view.path)if (index === -1) {return}state.visitedViews = state.visitedViews.filter((item, idx) => {if (idx >= index || (item.meta && item.meta.affix)) {return true}const i = state.cachedViews.indexOf(item.name)if (i > -1) {state.cachedViews.splice(i, 1)}return false})}
}const actions = {addView ({dispatch}, view) {dispatch('addVisitedView', view)dispatch('addCachedView', view)},addVisitedView ({commit}, view) {commit('ADD_VISITED_VIEW', view)},addCachedView ({commit}, view) {commit('ADD_CACHED_VIEW', view)},delView ({dispatch,state}, view) {return new Promise(resolve => {dispatch('delVisitedView', view)dispatch('delCachedView', view)resolve({visitedViews: [...state.visitedViews],cachedViews: [...state.cachedViews]})})},delVisitedView ({commit,state}, view) {return new Promise(resolve => {commit('DEL_VISITED_VIEW', view)resolve([...state.visitedViews])})},delCachedView ({commit,state}, view) {return new Promise(resolve => {commit('DEL_CACHED_VIEW', view)resolve([...state.cachedViews])})},delOthersViews ({dispatch,state}, view) {return new Promise(resolve => {dispatch('delOthersVisitedViews', view)dispatch('delOthersCachedViews', view)resolve({visitedViews: [...state.visitedViews],cachedViews: [...state.cachedViews]})})},delOthersVisitedViews ({commit,state}, view) {return new Promise(resolve => {commit('DEL_OTHERS_VISITED_VIEWS', view)resolve([...state.visitedViews])})},delOthersCachedViews ({commit,state}, view) {return new Promise(resolve => {commit('DEL_OTHERS_CACHED_VIEWS', view)resolve([...state.cachedViews])})},delAllViews ({dispatch,state}, view) {return new Promise(resolve => {dispatch('delAllVisitedViews', view)dispatch('delAllCachedViews', view)resolve({visitedViews: [...state.visitedViews],cachedViews: [...state.cachedViews]})})},delAllVisitedViews ({commit,state}) {return new Promise(resolve => {commit('DEL_ALL_VISITED_VIEWS')resolve([...state.visitedViews])})},delAllCachedViews ({commit,state}) {return new Promise(resolve => {commit('DEL_ALL_CACHED_VIEWS')resolve([...state.cachedViews])})},updateVisitedView ({commit}, view) {commit('UPDATE_VISITED_VIEW', view)},delRightTags ({commit}, view) {return new Promise(resolve => {commit('DEL_RIGHT_VIEWS', view)resolve([...state.visitedViews])})},delLeftTags ({commit}, view) {return new Promise(resolve => {commit('DEL_LEFT_VIEWS', view)resolve([...state.visitedViews])})}
}export default {namespaced: true,state,mutations,actions
}

2. tagviews文件引用

 (1)在 store/getters.js 引入

const getters = {.....
// 下方两句关键代码visitedViews: state => state.tagsView.visitedViews,cachedViews: state => state.tagsView.cachedViews
}export default getters

 (2)在 store/index.js 引入

....其他代码
// 关键代码
import tagsView from './modules/tagviews'.... 其他代码
export default new Vuex.Store({modules: {app,user,permission,// 关键代码tagsView},state: {},mutations: {},actions: {},getters
})

3. 更改routeview.vue 文件

 在 layouts/RouteView.vue 直接替换成以下代码

<template><keep-alive :include="cachedViews"><router-view :key="key" /></keep-alive>
</template>
<script>
export default {name: 'RouteView',computed: {cachedViews () {return this.$store.state.tagsView.cachedViews},key () {return this.$route.fullPath}},props: {keepAlive: {type: Boolean,default: true}},data () {return {}}}
</script>

4.更改mutiltable.vue文件

components/MultiTab/MultiTab.vue 中直接替换以下代码

<script>
import events from './events'export default {name: 'MultiTab',data () {return {fullPathList: [],pages: [],activeKey: '',newTabIndex: 0}},created () {// bind eventevents.$on('open', (val) => {console.log('table_open', val)if (!val) {throw new Error(`multi-tab: open tab ${val} err`)}this.activeKey = val}).$on('close', (val) => {if (!val) {this.closeThat(this.activeKey)return}this.closeThat(val)}).$on('rename', ({ key, name }) => {console.log('rename', key, name)try {const item = this.pages.find((item) => item.path === key)item.meta.customTitle = namethis.$forceUpdate()} catch (e) {}})this.pages.push(this.$route)this.fullPathList.push(this.$route.fullPath)this.selectedLastPath()},methods: {onEdit (targetKey, action) {this[action](targetKey)},remove (targetKey) {const newVal = this.getPage(targetKey)this.pages = this.pages.filter((page) => page.fullPath !== targetKey)this.fullPathList = this.fullPathList.filter((path) => path !== targetKey)if (newVal != null) {this.$store.dispatch('tagsView/delView', newVal)}// 判断当前标签是否关闭,若关闭则跳转到最后一个还存在的标签页if (!this.fullPathList.includes(this.activeKey)) {this.selectedLastPath()}},selectedLastPath () {this.activeKey = this.fullPathList[this.fullPathList.length - 1]},getPage (targetKey) {const newVal = this.pages.filter((c) => c.fullPath === targetKey)return newVal.length > 0 ? newVal[0] : null},// content menucloseThat (e) {// 判断是否为最后一个标签页,如果是最后一个,则无法被关闭if (this.fullPathList.length > 1) {this.remove(e)} else {this.$message.info('这是最后一个标签了, 无法被关闭')}},closeLeft (e) {const currentIndex = this.fullPathList.indexOf(e)if (currentIndex > 0) {this.fullPathList.forEach((item, index) => {if (index < currentIndex) {this.remove(item)}})} else {this.$message.info('左侧没有标签')}},closeRight (e) {const currentIndex = this.fullPathList.indexOf(e)if (currentIndex < this.fullPathList.length - 1) {this.fullPathList.forEach((item, index) => {if (index > currentIndex) {this.remove(item)}})} else {this.$message.info('右侧没有标签')}},closeAll (e) {const currentIndex = this.fullPathList.indexOf(e)this.fullPathList.forEach((item, index) => {if (index !== currentIndex) {this.remove(item)}})},refreshPage (e) {const currentIndex = this.fullPathList.indexOf(e)this.fullPathList.forEach((item, index) => {if (index === currentIndex) {let newVal = this.getPage(item)if (newVal != null) {const { path, query, matched } = newValmatched.forEach((m) => {if (m.components && m.components.default && m.components.default.name) {if (!['Layout', 'ParentView'].includes(m.components.default.name)) {newVal = { name: m.components.default.name, path: path, query: query }}}})console.log('refreshpage', newVal)this.$store.dispatch('tagsView/delCachedView', newVal).then((res) => {const { path, query } = newValthis.$router.replace({path: '/redirect' + path,query: query})})}}})},closeMenuClick (key, route) {this[key](route)},renderTabPaneMenu (e) {return (<a-menu{...{on: {click: ({ key, item, domEvent }) => {this.closeMenuClick(key, e)}}}}><a-menu-item key="closeThat">关闭当前标签</a-menu-item><a-menu-item key="closeRight">关闭右侧</a-menu-item><a-menu-item key="closeLeft">关闭左侧</a-menu-item><a-menu-item key="closeAll">关闭全部</a-menu-item><a-menu-item key="refreshPage">刷新标签</a-menu-item></a-menu>)},// renderrenderTabPane (title, keyPath) {const menu = this.renderTabPaneMenu(keyPath)return (<a-dropdown overlay={menu} trigger={['contextmenu']}><span style={{ userSelect: 'none' }}>{title}</span></a-dropdown>)},addtags () {const newVal = this.$routethis.$store.dispatch('tagsView/addView', newVal)}},mounted () {this.addtags()},watch: {$route: function (newVal) {this.activeKey = newVal.fullPaththis.addtags()if (this.fullPathList.indexOf(newVal.fullPath) < 0) {this.fullPathList.push(newVal.fullPath)this.pages.push(newVal)}},activeKey: function (newPathKey) {this.$router.push({ path: newPathKey })}},render () {const {onEdit,$data: { pages }} = thisconst panes = pages.map((page) => {return (<a-tab-panestyle={{ height: 0 }}tab={this.renderTabPane(page.meta.customTitle || page.meta.title, page.fullPath)}key={page.fullPath}closable={pages.length > 1}></a-tab-pane>)})return (<div class="ant-pro-multi-tab"><div class="ant-pro-multi-tab-wrapper"><a-tabshideAddtype={'editable-card'}v-model={this.activeKey}tabBarStyle={{ background: '#FFF', margin: 0, paddingLeft: '16px', paddingTop: '1px' }}{...{ on: { edit: onEdit } }}>{panes}</a-tabs></div></div>)}
}
</script>

5.生成路由地方配置,本文路由生成在 permission.js中,具体位置看项目

 注意事项:

        1、每个路由的name必须跟页面内的name一致,否则不会缓存

        2、路由当中的isCache 是控制多页签是否缓存重要属性(可自己控制是否缓存开关)

至此流程结束,多页签功能完成

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3019648.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

三、Redis五种常用数据结构-Hash

Hash是redis中常用的一种无序数据结构。结构类似HashMap。 具体结构如下&#xff1a;key field value 1、优缺点 1.1、优点 同类数据归类整合储存&#xff0c;方便数据管理。相比于string操作消耗内存和CPU更小。分字段存储&#xff0c;节省网络流量。 1.2、缺点 过期时间…

盘点一下近年来常用的电脑监控软件

企业电脑监控软件通常用于监视员工在工作时间内的电脑使用情况&#xff0c;以确保他们的工作效率和安全性。以下是几种常见的企业电脑监控软件&#xff1a; 1、Ping32 Ping32是一款集成多功能的企业级电脑监控软件&#xff0c;包括员工上网行为管理、文件外发审计、屏幕活动监…

Milvus Cloud 的RAG 的广泛应用及其独特优势

一个典型的 RAG 框架可以分为检索器(Retriever)和生成器(Generator)两块,检索过程包括为数据(如 Documents)做切分、嵌入向量(Embedding)、并构建索引(Chunks Vectors),再通过向量检索以召回相关结果,而生成过程则是利用基于检索结果(Context)增强的 Prompt 来激…

使用API有效率地管理Dynadot域名,设置所有域名默认whois信息

关于Dynadot Dynadot是通过ICANN认证的域名注册商&#xff0c;自2002年成立以来&#xff0c;服务于全球108个国家和地区的客户&#xff0c;为数以万计的客户提供简洁&#xff0c;优惠&#xff0c;安全的域名注册以及管理服务。 Dynadot平台操作教程索引&#xff08;包括域名邮…

WordPress与Joomla有哪些差异

在前不久遇到Hostease的客户在咨询WordPress和Joomla要如何选择。他们之间有哪些区别。Hostease提供的虚拟主机都可以直接安装这2个网站程序。下面针对WordPress和Joomla进行一些分析和比较。 WordPress和Joomla都是流行的内容管理系统&#xff08;CMS&#xff09;&#xff0c;…

2024年51cto下载的视频怎么导出

如果你喜欢在51cto上观看各种专业技术视频&#xff0c;那么你可能想将喜欢的视频保存到本地设备中&#xff0c;以便随时随地观看。今天&#xff0c;我们就来探讨一下如何在2024年将51cto下载的视频导出到你的设备中 下载51cto的工具我已经打包好了&#xff0c;有需要的自己下载…

AI换脸原理(4)——人脸对齐(关键点检测)参考文献2DFAN:代码解析

注意,本文属于人脸关键点检测步骤的论文,虽然也在人脸对齐的范畴下。 1、介绍 在本文中,重点介绍了以下几项创新性的成果,旨在为人脸关键点检测领域带来新的突破。 首先,成功构建了一个卓越的2D人脸关键点检测基线模型。这一模型不仅集成了目前最优的关键点检测网络结构,…

信息熵为凹函数-推导

凹函数和凸函数&#xff0c;是凹凸是相对于x轴来说的&#xff0c;对于熵来说&#xff0c;它是凹函数。因为它是-log函数&#xff0c;函数曲线相对于x轴来说是凸的。 Jensen不等式推导 以下是证明熵是凹函数。 引理&#xff1a; ①Jensen不等式&#xff0c;条件&#xff1a;…

SpringBoot框架如何接入RocketMQ?

目录 一、SpringBoot框架介绍 二、RocketMQ介绍 三、RocketMQ的应用场景 四、SpringBoot框架如何接入RocketMQ 一、SpringBoot框架介绍 Spring Boot是一个开源的Java框架,它基于Spring框架,旨在简化Java应用程序的开发。Spring Boot通过自动化配置和约定优于配置的原则,大…

谷歌开源!用 js 编写 Shell 脚本! | 开源日报 No.247

google/zx Stars: 41.4k License: Apache-2.0 zx 是一个用于编写更好脚本的工具。 提供有用的包装器&#xff0c;简化了对 child_process 的操作转义参数并提供合理的默认值使用 JavaScript 编写复杂脚本时比 Bash 更方便可以直接使用 npm 安装 dani-garcia/vaultwarden St…

评估Transitions

Stateflow使用图表中的转换从一种OR状态移动到另一种OR状态。对于图表执行的输入和执行工作流,Stateflow评估转换以确定它们是否有效。有效转换是条件标签为true且路径以状态结束的转换。如果转换有效,则Stateflow将从源状态退出并进入目标状态。 评估Transitions的工作流 T…

图搜索算法 - 拓扑排序

相关文章&#xff1a; 数据结构–图的概念 图搜索算法 - 深度优先搜索法&#xff08;DFS&#xff09; 图搜索算法 - 广度优先搜索法&#xff08;BFS&#xff09; 拓扑排序 概念 几乎所有的工程都可分为若干个称作活动的子工程&#xff0c;而这些子工程之间&#xff0c;通常受…

Debug项目失败Run成功

一&#xff1a;问题 idea中启动服务&#xff0c;服务一直在启动中&#xff0c;最后超时启动失败 重新构建项目也是一样 二&#xff1a;个人分析 debug因为断点太多了项目起不起来&#xff0c;试一下run直接运行&#xff0c;项目可以快速启动 三&#xff1a;解决办法 在控制…

四、Redis五种常用数据类型-List

List是Redis中的列表&#xff0c;按照插入顺序保存数据&#xff0c;插入顺序是什么样的&#xff0c;数据就怎么保存。可以添加一个元素到列表的头部(左边)或者尾部(右边)。一个列表最多可以包含232-1个元素(4294967295&#xff0c;每个列表超过40亿个元素)。是一种双向列表结构…

uniapp 如何修改 IPA 文件信息页的本地化语言

实现效果&#xff1a; 最终会对应到苹果商店的语言&#xff1a; 例如微信的语言就有多个&#xff1a; 操作&#xff1a; 在 mainfest.json 源码视图中加入&#xff1a; 具体对应的语言key值可以参考Xcode中的语言代码 这个取决于打包后的 lproj 文件 将后缀ipa改成zip打开即…

47. UE5 RPG 实现角色死亡效果

在上一篇文章中&#xff0c;我们实现了敌人受到攻击后会播放受击动画&#xff0c;并且还给角色设置了受击标签。并在角色受击时&#xff0c;在角色身上挂上受击标签&#xff0c;在c里&#xff0c;如果挂载了此标签&#xff0c;速度将降为0 。 受击有了&#xff0c;接下来我们将…

Linux中gitlab-runner部署使用备忘

环境&#xff1a; 操作系统:&#xff1a;CentOS8 gitlab版本&#xff1a;13.11.4 查看gitlab-runner版本 可以从https://packages.gitlab.com/app/runner/gitlab-runner/search找到与安装的gitlab版本相近的gitlab-runner版本以及安装命令等信息&#xff0c;我找到与13.11.4相…

C语言,实现数字谱到简谱的转换(二)

C语言&#xff0c;实现数字谱到简谱的转换&#xff08;二&#xff09; 前言&#xff1a;本文初编辑于2024年5月8日 CSDN&#xff1a;https://blog.csdn.net/rvdgdsva 博客园&#xff1a;https://www.cnblogs.com/hassle 前言 结合前文使用 之前的程序默认C调4/4拍&#xff…

windows11获取笔记本电脑电池健康报告

笔记本电脑的电池关系到我们外出时使用的安全&#xff0c;如果电池健康有问题需要及时更换&#xff0c;windows系统提供了检查电池健康度的方法。 1、打开命令行 1&#xff09;键入 winR 2&#xff09;键入 cmd 打开命令行。 2、在命令行运行如下指令&#xff0c;生成电池健…

美式期权和欧式期权区别的详细解析

美式期权和欧式期权的区别 美式期权和欧式期权是期权交易的两种主要形式&#xff0c;它们主要在行权时间、灵活性和价格等方面存在显著的区别。 文章来源/&#xff1a;股指研究院 美式期权的特点在于其买方可以在期权有效期内任何一天提出执行合约&#xff0c;即买方可以在到…