Vue3后退不刷新,前进刷新

核心思想

  1. 使用keep-alive缓存页面信息
  2. 由于vue3中keep-alive只能通过组件名称缓存,每次都会动态创建一个新的组件包装下页面
  3. 每次路由前进时会根据路由的深度分配一个uuid并缓存,然后用此uuid创建一个动态组件包装页面
  4. 此方法可以解决a->b->a->c 然后后退 c->a->b->a的问题

PageKeepAlive组件源码

vue 复制代码
<template>
  <keep-alive :include="include">
    <component v-if="node" :is="node" :key="data.cid" />
  </keep-alive>
</template>
<script setup>
import { uuid } from '@/common/utils/StringUtil'
import { defineComponent, computed, reactive, nextTick } from 'vue'
import {useRouter} from 'vue-router'
const props = defineProps(['data'])

const router = useRouter()

const comp_cache = reactive({})
const position_cache = reactive({})

const include = computed(()=>{
  let target = []
  let expired = new Set(Object.keys(comp_cache))
  for (let cache of Object.values(position_cache)) {
    target.push(cache.cid)
    expired.delete(cache.cid)
  }
  nextTick(()=>{ // 删除过期的缓存
    for (let cid of expired) {
      delete comp_cache[cid]
    }
  })
  return target
})

const node = computed(()=>{
  let data = props.data
  if(!data || !data.cid || !data.comps) return null
  if (!comp_cache[data.cid]) {
    comp_cache[data.cid] = defineComponent({
      name: data.cid,
      setup() {
        return () => data.comps
      }
    })
  }
  return comp_cache[data.cid]
})

router.afterEach((to) => {
  let current = window.history.state.position
  let path = to.path
  for (let i of Object.keys(position_cache)) {
    let cache = position_cache[i]
    if (i > current) { // 大于当前位置的缓存清理掉
      delete position_cache[i]
    }
    if (i == current && cache.path != path) { // replace需要去掉缓存
      delete position_cache[i]
    }
  }
  let cache = position_cache[current]
  if (!cache) {
    position_cache[current] = cache = {
      cid: `comp_${uuid()}`,
      path
    }
  }
  to.meta.cid = cache.cid
})
</script>

使用方式

vue 复制代码
<router-view v-slot="{ Component, route  }">
	<PageKeepAlive :data="{cid: route.meta.cid, comps: Component}" />
</router-view>
相关推荐
代码匠心13 小时前
AI 自动编程:一句话设计高颜值博客
前端·ai·ai编程·claude
_AaronWong14 小时前
Electron 实现仿豆包划词取词功能:从 AI 生成到落地踩坑记
前端·javascript·vue.js
cxxcode14 小时前
I/O 多路复用:从浏览器到 Linux 内核
前端
用户54330814419414 小时前
AI 时代,前端逆向的门槛已经低到离谱 — 以 Upwork 为例
前端
JarvanMo14 小时前
Flutter 版本的 material_ui 已经上架 pub.dev 啦!快来抢先体验吧。
前端
恋猫de小郭15 小时前
AI 可以让 WIFI 实现监控室内人体位置和姿态,无需摄像头?
前端·人工智能·ai编程
哀木15 小时前
给自己整一个 claude code,解锁编程新姿势
前端
程序员鱼皮15 小时前
GitHub 关注突破 2w,我总结了 10 个涨星涨粉技巧!
前端·后端·github
UrbanJazzerati15 小时前
Vue3 父子组件通信完全指南
前端·面试
是一碗螺丝粉15 小时前
5分钟上手LangChain.js:用DeepSeek给你的App加上AI能力
前端·人工智能·langchain