缓存id路由页面返回,历史路由栈

功能需求

网页端需要做页面数据缓存(vue动态路由数据缓存),可根据id值打开多个编辑详情页,需要在页面操作返回时关闭面包屑页签

隐藏问题

1.页面缓存会有初始化和组件激活访问生命周期调用数据接口过多,有性能损耗
2.使用this.$router.back()返回是返回上一个历史路由,如果打开多个id详情页,并反复在两个详情页做切换操作,会导致在操作返回时看起来像是在详情页反复切换数据关闭不了,如下图



解决

1.缓存页组件初始化(created)和组件激活访问(activated)生命周期只执行一次,使用变量状态,在进入方法时判断变量是否return,在接口完成(finally)更改变量

2.路由历史栈,在路由守卫router.beforeEachstore存储from历史路由,在标题组件返回方法里,对历史路由栈数据进行操作,获取历史有效路由使用this.$router.replace跳转

javascript 复制代码
//在面包屑页签组件初始化时调用addTags方法存储访问路由
addTags() {
  const { name } = this.$route
  if (name) {
    this.$store.dispatch('tagsView/addView', this.$route)
  }
},


//在权限管理路由守卫里存储历史访问路由
import store from './store'
router.beforeEach(async (to, from, next) => {
  ...
  store.commit('tagsView/ADD_ROUTER_HISTORY', from.path);
  ...
}

tagsView.js文件

javascript 复制代码
const state = {
  visitedViews: [],
  cachedViews: [],
  routeHistory: [],
  closedRoutes: [],
  validHistory:[],
  lastValidRoute:''
}
const mutations = {
  ADD_ROUTER_HISTORY: (state, path) => {
    state.routeHistory.push(path);
  },
  CLOSE_ROUTER(state, route) {
    state.closedRoutes.push(route);
    // 生成过滤后的有效历史栈
    state.validHistory = state.routeHistory.filter(item => !state.closedRoutes.includes(item))

    if (state.cachedViews.length===0) {
      //首页
      state.lastValidRoute = '/'  
    }else{
      //历史有效路由
      state.lastValidRoute = state.validHistory[state.validHistory.length - 1];  
    }
  },
  ADD_VISITED_VIEW: (state, view) => {
    if (state.visitedViews.some(v => v.path === view.path)) return
    state.visitedViews.push(
      Object.assign({}, view, {
        title: view.meta.title || 'no-name'
      })
    )
  },
  ADD_CACHED_VIEW: (state, view) => {
    if (state.cachedViews.includes(view.name)) return
    if (!view.meta.noCache) {
      state.cachedViews.push(view.name)
    }
    console.log(state.cachedViews)
  }
}
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])
    })
  }
}
export default {
  namespaced: true,
  state,
  mutations,
  actions
}

标题组件layout-header.vue文件返回方法里应用

html 复制代码
<template>
  <div class="layout-header">
    <div class="back" v-if="back" @click="handleBack">
      <img src="@/assets/images/back-icon.png"/>
    </div>
    <div class="layout-title" :style="'font-size:' + fontSize + 'px' ">{{title}}</div>
    <slot></slot>
  </div>
</template>
javascript 复制代码
<script>
export default {
  props: {
    title: {
      type: String,
      default: ""
    },
    back: {
      type: Boolean,
      default: false
    },
    fontSize: {
      type: Number,
      default: 18
    }
  },
  data() {
    return {

    }
  },
  methods: {
    handleBack(){
      let path = this.$route.path
      //存入当前路由
      this.$store.commit('tagsView/ADD_ROUTER_HISTORY', path);
      const visitedViews=this.$store.state.tagsView.visitedViews
      let view = visitedViews.find(v => v.path === path)
      //计算路由历史栈及访问路由
      this.$store.commit('tagsView/CLOSE_ROUTER', path);
      this.$store.dispatch('tagsView/delView', view)
      // 获取最近有效路由并跳转
      const target = this.$store.state.tagsView.lastValidRoute
      this.$router.replace(`${target}`);
    }
  }
}
</script>
相关推荐
鹏多多1 小时前
PC 网站接入微信登录,这 10 个坑我替你踩完了!
前端·javascript·vue.js
草莓熊Lotso4 小时前
【Redis 初阶】Set 类型深度解析:去重集合的运算能力与实战场景
linux·网络·数据库·windows·redis·tcp/ip·缓存
染指11105 小时前
103.RAG-LLamaIndex后端rag问答-聊天接口
前端·javascript·vue.js·人工智能
单线程_0113 小时前
从案例分析 Vue3 Tokenizer+Parser 源码三
前端·javascript·vue.js
jay神14 小时前
【计算机毕业设计】基于SpringBoot的程序教学辅助系统
java·前端·vue.js·spring boot·后端·毕业设计·课程设计
云存储小天使18 小时前
训练效率提升50%以上:GooseFS 写缓存及其在具身智能数据处理中的应用
缓存·腾讯云·对象存储·goosefs
OpenTiny社区20 小时前
从流式消息到多会话:TinyRobot Kit 如何组织 AI 对话数据层
vue.js
程序员夏洛21 小时前
Redis 数据过期后的删除策略是什么?
数据库·redis·缓存
鱼鳞_21 小时前
热门八股-Redis
数据库·redis·缓存
卤蛋fg61 天前
vue表格组件 vxe-table 鼠标滑动表头选择整列与选择整行的配置详解
vue.js