前言
脆皮打工人又感冒了,一直咳嗽流鼻涕,真的难搞。所以这几天我也没学习,一直摆烂打打游戏,看看电影啥的,最近遇到个keep-alive的问题,刚好可以顺便重新学习记录下keep-alive的使用。
vue2
首先讲一下vue2中如何使用keep-alive
使用vite创建vue2
bash创建
1 | npm init vite |
接下来的名称什么的随便搞一个,然后创建类型选择vanilla
,而不是vue,因为选择vue创建的是vue3的
安装依赖
首先我们需要安装vite支持vue2的依赖
1 | npm install vite-plugin-vue2 |
然后安装vue,需要带上版本号,你可以先按照我的版本来,但是估计有问题
1 | npm install vue@2.7.16 |
创建修改文件
根目录创建vite.config.js
1 | // vite.config.js |
创建src,将main.js放到src目录下
1 | // main.js |
index.html依赖导入修改
1 | <script type="module" src="/src/main.js"></script> |
src下创建App.vue,随便写点东西
1 | <template> |
此时npm install将我们vite原先需要的依赖全部安装完成,再npm run dev
启动即可
编译版本和vue2版本冲突
还记得我说过的你随便安装一个版本可能会报错吗
其实解决方案他也给你了,你只需要将vue版本安装成他的编译版本就可以了This may cause things to work incorrectly. Make sure to use the same version for both.
我这里的版本是2.7.16
,所以我需要执行的是npm install vue@2.7.16
安装并使用路由
这里考点来了,vue2支持的vue-router@3x,别安装最新的即可
配置@
这里为了书写简单点,我在vite.config.ts中进行了@符号的配置
1 | // vite.config.js |
配置路由
src下新建一个router文件夹,再新建一个index.js,里面写上这些代码,这里也有个考点,路由的模式,比如history,hash,这有什么区别,
- 最明显的区别就是url看上去不太一样,一个有#,一个没有
- history发布时候需要进行配置,而hash不用
- 还有就是build之后的dist文件夹,如果是history模式,并且服务端此时没有进行相应的配置,live-server打开那个index.html也是空白的将App.vue进行修改
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26import Vue from "vue";
import Router from "vue-router";
Vue.use(Router);
export const constantRoutes = [
{
path:"/",
redirect:"/home"
},
{
path: "/about",
name: "About",
component: () => import("@/views/about/index.vue"),
},
{
path: "/home",
name: "Home",
component: () => import("@/views/home/index.vue"),
},
];
export const router = new Router({
mode: "history", // 需要服务端支持
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes,
});main.js中进行路由导入1
2
3
4
5
6
7
8
9
10
11<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "App",
};
</script>1
2
3
4
5
6
7
8
9
10// main.js
import Vue from "vue";
import App from "./App.vue"
import { router } from "./router/index.js";
new Vue({
router,
el: "#app",
render: (h) => h(App)
}).$mount();
然后根据路径去把home和about创建出来即可
为了方便切换路由,加个切换路由的按钮
新建一个layout文件夹,下面新建一个index.vue文件
1 | <template> |
将路由进行切换
1 | export const constantRoutes = [ |
然后我将关于页面进行了修改,首页也是类似的修改
1 | <template> |
测试keep-alive
无keep-alive效果
ok,到这里,我们先来测试一下,keep-alive生效和没生效的区别吧,此时我们是没有加上keep-alive的
添加keep-alive
通过下面这个视频我们可以看到,当我们切换路由的时候,我们输入的内容并没有保存住,然后我们加上keep-alive
1 | <transition name="fade-transform" mode="out-in"> |
我们可以看到,我们输入的内容被保存住了,切换路由回来,内容依旧是在的
keep-alive属性
但是一般我们不可能给所有路由都加上keep-alive,这里就用到了我们keep-alive的俩个属性
- include
- exclude
这俩个属性,分别是对某些缓存,某些不换存,并且要求name值和我们组件暴露的name值要相等,我们一个个实验一下,首先是include此时我们的首页有个name也是1
2
3<keep-alive :include="['Home']">
<router-view :key="$route.path" />
</keep-alive>Home
的此时的效果如下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16<template>
<div class="home">
<div>首页</div>
<input type="text" placeholder="首页" v-model="inputValue">
</div>
</template>
<script>
export default {
name:"Home",
data() {
return {
inputValue: "",
};
},
}
</script>
同样的,我们实验一下exclude
1 | <keep-alive :exclude="['About']"> |
不出所料,实现效果和上面的视频一模一样
vue3
vue3中的keep-alive改造写法
接下来还有一些keep-alive的知识与细节,我们通过vue3来讲解,vue3的项目创建可就太简单了,大家有不会的可以参考我之前的很多文章
我将Home改成了这样,About也是类似的
1 | <template> |
然后将layout也改了,这里我们可以看到vue3中的写法和vue2稍微有点不一样
1 | <template> |
keep-alive中key值的作用
接下来,我们来了解一下为什么要加:key这个属性,其中最主要的原因就是component他的is指向的Component
并没有改变,在vue2中的写法,你也可以理解为路由没有改变,你说这是什么情况会发生的呢,我给大家举个例子。
这里我加了一个路由
1 | { |
然后我把routerLink进行了填充
1 | <header class="app-header"> |
然后写了一个user的文件
1 | <template> |
此时的效果是正常的,内容是有缓存住的
如果我们这个key去掉,就会发生很有趣的事情
这样使用一个组件的内容,keep-alive根本没识别到切换,因此这个key值是非常有必要的
keep-alive生命周期
没错,keep-alive也是有生命周期的,当我们的keep-alive生效的时候
会多出来俩个生命周期activated和deactivated,在vue3中的写法就是onActivated和onDeactivated
我们来测试一下,我将首页代码改成了这样,加上了生命周期
1 | <template> |
我们可以清晰看到,onMounted只执行了一次,onActivated在每次进入缓存页面时候触发,onDeactivated在每次离开缓存页面的时候触发。
iframe内嵌网页的keep-alive
可以参考我这篇文章的实现,就不多赘述了
https://myblog-5g89ixpbbf1fbfad-1316695488.ap-shanghai.app.tcloudbase.com/2023/06/14/iframe-save-refresh/
我遇到的揪心bug
说到了这还没讲我遇到的bug呢,这个当时也没考虑那么周全,之前我封装了一个业务编辑器组件,他里面的字段真的很多,然后内容也很多,我就拆了很多组件一个个写起来的,为了值方便管理,我把所有的v-model都绑定到了store的值,后续这个组件发包了,就是普通的私有域的npm包,然后在现在要用的时候,结合keep-alive使用就出现了问题,因为需求是多个tag打开同一个这个组件进行编辑,但是因为值都是使用那个组件里面的store,就导致了我的值进行了污染。
结语
本篇文章就先到这里了,更多内容敬请期待,债见~