vue3使用keep-alive做缓存;vue3实现beforeRouteEnter

使用缓存前,建议先读一遍官方文档 ;以及可以先注意本文列举的注意项和不生效原因

一、使用keep-alive的两种方式

1.通过v-if="$route.meta.keepAlive"方式

1.1代码:

注意:一定要设置:key,否则在两个都是缓存的页面跳转回报错

  {{$route.meta}}-{{$route.meta.keepAlive}}
  <router-view v-slot="{ Component }">
    <!-- 一定要设置:key="route.name" 否则在两个连续缓存页跳转会报错 -->
    <keep-alive>
      <component v-if="$route.meta.keepAlive" :key="$route.path" :is="Component" />
    </keep-alive>
    <component v-if="!$route.meta.keepAlive" :key="$route.path" :is="Component" />
  </router-view>

1.2配置对用keepAlive

这里是引用

2.通过include方式

2.1代码:

  • 注意::include="[‘experienceMaintenance’, ‘realTimeAlarm’]"使用的是vue页name,不是路由的name
  • 建议: vue页name和路由的name保持一致,这样在做缓存时候,方便监听存入
  <router-view v-slot="{ Component }">
    <!--:key 每次切换时,通过修改 key 的值,可以避免缓存中的组件被复用,从而达到刷新组件的目的-->
    <!-- :key="$route.path" -->
    <keep-alive :include="['DeviceList','ExperienceMaintenance', 'RealTimeAlarm']">
      <component :is="Component"></component>
    </keep-alive>
  </router-view>

监听路由变化

watch(route, val => {
  const { path, matched } = val
  if (!matched.length) return
  console.log('页签监听', path, val, matched,)
  console.log('vue组件名name和vue路由name设置一致,就可以直接取该name存入缓存集合', val.name);
  // let keepAliveName = matched[matched.length - 1].name
  // console.log('keepAliveName', keepAliveName);

}, { immediate: true, deep: true })

1.2设置对应vue页组件name

在这里插入图片描述

3.区别

  • 使用v-if=的方式,配置简单。只需要在路由文件里给需要缓存的配置keepAlive meta: { title: "经验维护", keepAlive: true }
  • 使用include的需要给每一个vue页配置name,很麻烦。但是该方式的应该有优点吧? ; 例如一个vue页面可以缓存具体的组件

二、keep-alive缓存不生效原因

1.路由文件配置有误

  • 在路由文件里面,将需要keep-alive的页面放在layout组件的children里面(如果不放在children里面keep-alive就不会生效)—layout组件就是你写keep-alive的那个组件;需要给要缓存的页面的一级菜单配置相同的component
  • 例子:有A、B、C三个一级菜单,其下下分别有对应a1、a2、b1、b2、c1、c2的二级路由,且都要缓存。那么ABC的三个一级菜单的component:引入需要一致;否则a1、a2跳转时候缓存正常,但是a1、b1、c1这种跨了不同一级菜单的相互跳转,会发现缓存不生效。
    在这里插入图片描述

2.使用include设置name不生效

  • 注意name应该是vue页面的name,不是路由里的name
  • 需要使用:key=区分 否则切换路由报错

3.使用了双视图

双视图:好比入口文件index.vue里有两个< router-view>< /router-view>;通常是一个视图给首页、登录页(不需要导航栏的页面)使用,一个给正常内容区页面使用。
问题:使用双视图就会导致,在两个视图之前的菜单页面切换,会清空彼此缓存;单个视图内的菜单切换缓存依旧生效
解决:只能通过v-if控制样式和div,硬改成一个router-view视图;暂时没有找到好的方案(能否使用router-view的name属性解决?有好方案可以评论提供下谢谢!)。
在这里插入图片描述

4.使用嵌套路由

那么需要给最内层的router-view加上keep-alive逻辑,同时需要给其他外层的router-view的 :key 去除掉

5.使用对用钩子函数

  • vue导航守卫触发实际和顺序
  • 首先vue3是onBeforeRouteLeave这个钩子的,但是beforeRouteEnter钩子函数不存在了;不过可以通过代码实现beforeRouteEnter钩子函数

3.1 正常使用onBeforeRouteLeave

<script setup>
import { ref, onMounted, onActivated, onDeactivated} from "vue"
import { onBeforeRouteLeave } from 'vue-router'
onActivated(() => {
  console.log('onActivated');
  // 调用时机为首次挂载
  // 以及每次从缓存中被重新插入时
})

onDeactivated(() => {
  console.log('onDeactivated');
  // 在从 DOM 上移除、进入缓存
  // 以及组件卸载时调用
})

const doing = () => {
 
}

// 将变量和函数返回,以便在模版中使用
onBeforeRouteLeave((to, from, next) => {
  console.log('onBeforeRouteLeave==',to, from.meta, next);
  //  from.meta.keepAlive = false
  //  console.log(from.meta);
  doing()
  next()
  // const cacheList = ['组织']
  // if (cacheList.indexOf(to.name) === -1) {
  //  	doing()
  //   nextTick(() => {
  //   })
  // }
})

// * 用到的方法,需要暴露出来
defineExpose({ doing })

3.2 实现beforeRouteEnter

<script setup>
	defineOptions({
	  name: 'ExperienceMaintenance',
	  beforeRouteEnter(_to, _from, next) {
	    console.log('beforeRouteEnter执行',_to, _from, next);
	    next((vm) => {
	      const instance = vm
	      instance.getData() // 刷新列表数据(不缓存)
	    })
	  }
	})
	
	const getData = async () => {
	  console.log('出发对应方法');
	}
	
	// * beforeRouteEnter中要用到的方法,需要暴露出来
	defineExpose({ getData })

</script>

参考点:路由配置里也有独享的守卫beforeEnter

三、注意项

1.报错[vite] Internal Server Error expects exactly one child component.at createCompilerError

报错:
这里是引用

原因: 由于 <keep-alive> 是一个组件,而不是普通的HTML标签,所以在其内部是不能直接写注释的
方法:在这里插入图片描述

2.报错TypeError: parentComponent.ctx.deactivate is not a function

这里是引用
注意:一定要设置:key,否则在两个都是缓存的页面跳转回报错

### Intellij IDEA Stash 使用方法与常见问题 #### 创建 Stash 当开发者希望保存当前工作进度而不提交更改时,可以使用 `Stash` 功能。这允许临时存储未完成的工作以便切换到其他分支或其他任务。 在 IntelliJ IDEA 中创建一个新的 stash 非常简单: 1. 打开版本控制工具窗口 (View | Tool Windows | Version Control)。 2. 切换至 Local Changes 标签页。 3. 右键点击想要 stashed 的变更文件并选择 "Shelve changes..." 或者直接通过 VCS 菜单下的 “Stash” -> “Stash Untracked Files...”。 此过程会将所有选中的修改存入一个名为 stash 的列表里[^1]。 #### 应用已有的 Stash 如果之前已经创建过一些 stash 并且现在需要恢复这些改动,则可以通过如下方式来应用它们: 1. 同样是在版本控制系统视图内找到 Stashes 小节; 2. 展开该部分查看所有的历史记录条目; 3. 单击右键于目标项上然后选取 Apply 选项即可把对应的差异重新引入项目之中; 值得注意的是,在执行 apply 操作前应当确认本地没有冲突性的变动存在以免引起不必要的麻烦。 #### 删除不再需要的 Stash 对于那些已经被成功合并或是确实不需要再保留下来的 stash 条目来说,应该及时清理掉以保持整洁有序的状态管理空间: - 在上述提到过的同一位置处定位到待删除的对象之后, - 进行同样的鼠标右键菜单操作但是这次要挑选 Pop 或 Delete 命令来进行相应处理。 以上就是关于如何利用IntelliJ IDEA内置Git插件所提供的stash特性的一些基本介绍以及实际应用场景下可能遇到的问题解决方案。 ```bash git stash save "message" git stash list git stash pop git stash drop ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值