Js 面向对象 动态添加标签页
[详细] -->
赞
踩
赞
踩
整体思路
1. 封装自定义tabbar组件 需要监听当前的路由路径,当路由发生变化的时候,需要存tabslist和 keepaliveName的数据
2. 封装存储和移除tabsList的数据的方法(pinia)用于显示页签
3. 封装缓存和移除的组件名字keepaliveName的方法(pinia)用于keepalive组件的include属性
4. 在路由出口的位置需要使用keepalive组件和component组件 缓存组件的数据 实现切换tab后,上一tab页的内容仍然保留
第一步 封装自定义tabbar组件
- <div class="tabs-box">
- <div class="tabs-menu">
- <el-tabs
- v-model="tabsMenuValue"
- type="card"
- @tab-click="tabClick"
- @tab-remove="tabRemove"
- >
- <el-tab-pane
- v-for="item in tabsMenuList"
- :key="item.path"
- :label="item.title"
- :name="item.path"
- :closable="item.close"
- >
- <template #label>
- <el-icon class="tabs-icon" v-show="item.icon && tabsIcon"></el-icon>
- {{ item.title }}
- </template>
- </el-tab-pane>
- </el-tabs>
- </div>
- </div>
-
-
- // Tab Click 点击每一个tab跳转到对应的页面
- const tabClick = (tabItem: TabsPaneContext) => {
- const fullPath = tabItem.props.name as string
- console.log('fullPath', fullPath)
- router.push(fullPath)
- }
-
- // Remove Tab 点击每一个tab上的icon移除当前tab
- const tabRemove = (fullPath: TabPaneName) => {
- //tab-remove方法 会返回一个回调函数 fullpath
- console.log('fullPath', fullPath)
- const name =
- tabStore.tabsMenuList.filter((item: any) => item.path == fullPath)[0]
- .name || ''
- // 移除keepaliveName和tabsList的数据
- keepAliveStore.removeKeepAliveName(name)
- tabStore.removeTabs(fullPath as string, fullPath == route.fullPath)
- }
-
- // 监听路由的变化(防止浏览器后退/前进不变化 tabsMenuValue)
- watch(
- () => route.fullPath,
- () => {
- const routeList = route.fullPath.split('/')
- const name = routeList[routeList.length - 1]
- tabsMenuValue.value = route.fullPath
- const tabsParams = {
- icon: route.meta.icon as string,
- title: route.meta.title as string,
- path: route.fullPath,
- name: name as string,
- close: true,
- }
- // 当路由发生变化时 给tabsList 和 keepaliveName中添加数据
- tabStore.addTabs(tabsParams)
- keepAliveStore.addKeepAliveName(name)
- },
- // 一来进来页面就监听
- { immediate: true },
- )
第二步 封装存储和移除tabsList的数据的方法
- // addtab
- async addTabs(tabItem: TabsMenuProps) {
- //要往tabsList添加的tab 是否在list中,如果不在就添加
- console.log('tabItem', tabItem)
- const res1 = this.tabsMenuList.every((item) => {
- console.log('item', item)
- return item.path !== tabItem.path
- })
- console.log('res1', res1)
- if (this.tabsMenuList.every((item) => item.path !== tabItem.path)) {
- this.tabsMenuList.push(tabItem)
- console.log('tabsMenuList', this.tabsMenuList)
- }
- },
- // Remove Tabs
- async removeTabs(tabPath: string, isCurrent: boolean = true) {
- // isCurrent 判断当前的fullpath和路由获取到的fullpath 是否一致
- // 1. 把当前tabs关闭
- // 2. 显示上一个tabs内容
- const tabsMenuList = this.tabsMenuList
- if (isCurrent) {
- tabsMenuList.forEach((item, index) => {
- if (item.path !== tabPath) return
- // ?什么情况下会 加1 显示上一个tabs内容
- const nextTab = tabsMenuList[index + 1] || tabsMenuList[index - 1]
- if (!nextTab) return
- router.push(nextTab.path)
- })
- }
- //把当前tabs关闭
- this.tabsMenuList = tabsMenuList.filter((item) => item.path !== tabPath)
- },
第三步 封装缓存和移除的组件名字keepaliveName的方法
- // Add KeepAliveName
- async addKeepAliveName(name: string) {
- !this.keepAliveName.includes(name) && this.keepAliveName.push(name)
- // console.log('keepAliveName3333333', this.keepAliveName)
- },
- // Remove KeepAliveName
- async removeKeepAliveName(name: string) {
- this.keepAliveName = this.keepAliveName.filter((item) => item !== name)
- },
第四步 在路由出口的位置缓存数据
- <router-view v-slot="{ Component }">
- <!-- transition 过渡动画 -->
- <transition name="fade">
- <!-- 渲染layout一级路由组件的子路由 -->
- <!--:key 每次切换时,通过修改 key 的值,可以避免缓存中的组件被复用,从而达到刷新组件的目的-->
- <keep-alive :include="keepAliveName">
- <component :is="Component" v-if="flag" :key="route.path" />
- </keep-alive>
- </transition>
- </router-view>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。