搜索
您的当前位置:首页keep-alive在vue2中应该怎样使用

keep-alive在vue2中应该怎样使用

时间:2023-11-30 来源:乐玩宠

这次给大家带来keep-alive在vue2中应该怎样使用,keep-alive在vue2中使用的注意事项有哪些,下面就是实战案例,一起来看一下。

keep-alive 是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。结合vue-router中使用,可以缓存某个view的整个内容。

基本使用如下:

<keep-alive> <component> <!-- 该组件将被缓存! --> </component></keep-alive>

一般有这样的需求,当我们第一次进入列表页需要请求一下数据,当我从列表页进入详情页,详情页不缓存也需要请求下数据,然后返回列表页

有两个情况:

1. 直接点击浏览器的后退返回按钮。

2. 点击导航栏中的 /list的链接返回。

那么针对第一种情况下,我们直接通过后退按钮时,返回到列表页(/list) 是不需要请求数据。

针对第二种情况下,我们通过链接返回到列表页是需要请求数据。

所以这边有三种情况:

1. 默认进来列表页需要请求数据。

2. 进入详情页后,通过浏览器默认后退按钮返回,是不需要ajax的请求的。

3. 进入详情页后,通过点击链接返回到列表页后,也是需要发ajax请求的。

配置如下:

1. 入口文件 app.vue 的配置如下:

<!-- 缓存所有的页面 --><keep-alive> <router-view v-if="$route.meta.keep_alive"></router-view></keep-alive><router-view v-if="!$route.meta.keep_alive"></router-view>

2. 在router中设置meta属性,设置 keepAlive: true 表示需要使用缓存,false的话表示不需要使用缓存。且添加滚动行为 scrollBehavior

router/index.js 的配置如下:

import Vue from 'vue';import Router from 'vue-router';// import HelloWorld from '@/views/HelloWorld';Vue.use(Router);const router = new Router({ mode: 'history', // 访问路径不带井号 需要使用 history模式,才能使用 scrollBehavior base: '/page/app', // 配置单页应用的基路径 routes: [ { path: '/', name: 'list', component: resolve => require(['@/views/list'], resolve), // 使用懒加载 meta: { keepAlive: true // true 表示需要使用缓存 } }, { path: '/list', name: 'list', component: resolve => require(['@/views/list'], resolve), // 使用懒加载 meta: { keepAlive: true // true 表示需要使用缓存 false表示不需要被缓存 } }, { path: '/detail', name: 'detail', component: resolve => require(['@/views/detail'], resolve) // 使用懒加载 } ], scrollBehavior (to, from, savedPosition) { // 保存到 meta 中,备用 to.meta.savedPosition = savedPosition; if (savedPosition) { return { x: 0, y: 0 }; } return {}; }});export default router;

3. list.vue 代码如下:

<template> <p class="hello"> <h1>vue</h1> <h2>{{msg}}</h2> <router-link to="/detail">跳转到detail页</router-link> </p></template><script>export default { name: 'helloworld', data () { return { msg: 'Welcome to Your Vue.js App' }; }, methods: { ajaxRequest() { const obj = { 'aa': 1 }; Promise.all([this.$store.dispatch('testUrl', obj)]).then((res) => { console.log(res); }); } }, beforeRouteEnter(to, from, next) { next(vm => { /* 如果 to.meta.savedPosition === undefined 说明是刷新页面或可以叫第一次进入页面 需要刷新数据 如果savedPosition === null, 那么说明是点击了导航链接; 此时需要刷新数据,获取新的列表内容。 否则的话 什么都不做,直接使用 keep-alive中的缓存 */ if (to.meta.savedPosition === undefined) { vm.ajaxRequest(); } if (to.meta.savedPosition === null) { vm.ajaxRequest(); } }) }};</script>

4. detail.vue 代码如下:

<template> <p class="list"> <h1>{{msg}}</h1> <router-link to="/list">返回列表页</router-link> </p></template><script>export default { name: 'list', data () { return { msg: 'Welcome to Your Vue.js App' }; }, created() { this.ajaxRequest(); }, methods: { ajaxRequest() { const obj = { 'aa': 1 }; Promise.all([this.$store.dispatch('withdary', obj)]).then((res) => { console.log(res); }); } }};</script>

二:使用router.meta 扩展

假设现在有3个页面,需求如下:

1. 默认有A页面,A页面进来需要一个请求。

2. B页面跳转到A页面,A页面不需要重新请求。

3. C页面跳转到A页面,A页面需要重新请求。

实现方式如下:

在 A 路由里面设置 meta 属性:

{ path: '/a', name: 'A', component: resolve => require(['@/views/a'], resolve), meta: { keepAlive: true // true 表示需要使用缓存 }}

所以router/index下的所有代码变为如下:

import Vue from 'vue';import Router from 'vue-router';// import HelloWorld from '@/views/HelloWorld';

Vue.use(Router);

const router = new Router({ mode: 'history', // 访问路径不带井号 需要使用 history模式,才能使用 scrollBehavior base: '/page/app', // 配置单页应用的基路径 routes: [ { path: '/', name: 'list', component: resolve => require(['@/views/list'], resolve), // 使用懒加载 meta: { keepAlive: true // true 表示需要使用缓存 } }, { path: '/list', name: 'list', component: resolve => require(['@/views/list'], resolve), // 使用懒加载 meta: { keepAlive: true // true 表示需要使用缓存 false表示不需要被缓存 } }, { path: '/detail', name: 'detail', component: resolve => require(['@/views/detail'], resolve) // 使用懒加载 }, { path: '/a', name: 'A', component: resolve => require(['@/views/a'], resolve), meta: { keepAlive: true // true 表示需要使用缓存 } }, { path: '/b', name: 'B', component: resolve => require(['@/views/b'], resolve) }, { path: '/c', name: 'C', component: resolve => require(['@/views/c'], resolve) } ], scrollBehavior (to, from, savedPosition) { // 保存到 meta 中,备用 to.meta.savedPosition = savedPosition; if (savedPosition) { return { x: 0, y: 0 }; } return {}; }});export default router;

在 B 组件里面设置 beforeRouteLeave

beforeRouteLeave(to, from, next) { // 设置下一个路由meta to.meta.keepAlive = true; // 让A缓存,不请求数据 next(); // 跳转到A页面}

B组件所有代码如下:

<template> <p class="list"> <h1>{{msg}}</h1> <router-link to="/a">返回a页面</router-link> </p></template><script>export default { name: 'list', data () { return { msg: 'Welcome to B Page' }; }, created() {}, methods: { }, beforeRouteLeave(to, from, next) { // 设置下一个路由meta to.meta.keepAlive = true; // 让A缓存,不请求数据 next(); // 跳转到A页面 }};</script>

在 C 组件里面设置 beforeRouteLeave:

beforeRouteLeave(to, from, next) { // 设置下一个路由meta to.meta.keepAlive = false; // 让A不缓存,重新请求数据 console.log(to) next(); // 跳转到A页面}

c组件所有代码如下:

<template> <p class="list"> <h1>{{msg}}</h1> <router-link to="/a">返回a页面</router-link> </p></template><script>export default { name: 'list', data () { return { msg: 'Welcome to B Page' }; }, created() {}, methods: { }, beforeRouteLeave(to, from, next) { // 设置下一个路由meta to.meta.keepAlive = false; // 让A不缓存,重新请求数据 console.log(to) next(); // 跳转到A页面 }};</script>

a组件内的所有的代码如下:

<template> <p class="hello"> <h1>vue</h1> <h2>{{msg}}</h2> <router-link to="/b">跳转到b页面</router-link> <router-link to="/c">跳转到c页面</router-link> </p></template><script>export default { name: 'helloworld', data () { return { msg: 'Welcome to A Page' }; }, methods: { ajaxRequest() { const obj = { 'aa': 1 }; Promise.all([this.$store.dispatch('testUrl', obj)]).then((res) => {}); } }, beforeRouteEnter(to, from, next) { next(vm => { /* 如果 to.meta.savedPosition === undefined 说明是刷新页面或可以叫第一次进入页面 需要刷新数据 如果to.meta.keepAlive === false, 那么说明是需要请求的; 此时需要刷新数据,获取新的列表内容。 否则的话 什么都不做,直接使用 keep-alive中的缓存 */ if (to.meta.savedPosition === undefined) { vm.ajaxRequest(); } if (!to.meta.keepAlive) { vm.ajaxRequest(); } }) }};</script>

注意 b组件到a组件不重新请求数据 (包括点击链接和浏览器后退按钮),c组件到a组件请求数据(包括点击链接和浏览器后退按钮).

相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!

推荐阅读:

nodejs怎么实现gulp打包功能

webpack构建多页面应用的步骤分析

小编还为您整理了以下内容,可能对您也有帮助:

vue的keep-alive组件的使用及其实现原理

keep-alive是Vue.js的一个内置组件。它能够把不活动的组件实例保存在内存中,而不是直接将其销毁,它是一个抽象组件,不会被渲染到真实DOM中,也不会出现在父组件链中。

它提供了include与exclude两个属性,允许组件有条件地进行缓存。

具体内容可以参考 官网 。

用法

这里的component组件会被缓存起来。

举个栗子

在点击button时候,coma与comb两个组件会发生切换,但是这时候这两个组件的状态会被缓存起来,比如说coma与comb组件中都有一个input标签,那么input标签中的内容不会因为组件的切换而消失。

props

keep-alive组件提供了include与exclude两个属性来允许组件有条件地进行缓存,二者都可以用逗号分隔字符串、正则表达式或一个数组来表示。

将缓存name为a的组件。

name为a的组件将不会被缓存。

生命钩子

keep-alive提供了两个生命钩子,分别是activated与deactivated。

因为keep-alive会将组件保存在内存中,并不会销毁以及重新创建,所以不会重新调用组件的created等方法,需要用activated与deactivated这两个生命钩子来得知当前组件是否处于活动状态。

说完了keep-alive组件的使用,我们从源码角度看一下keep-alive组件究竟是如何实现组件的缓存的呢?

created与destroyed钩子

created钩子会创建一个cache对象,用来作为缓存容器,保存vnode节点。

destroyed钩子则在组件被销毁的时候清除cache缓存中的所有组件实例。

render

首先通过getFirstComponentChild获取第一个子组件,获取该组件的name(存在组件名则直接使用组件名,否则会使用tag)。接下来会将这个name通过include与exclude属性进行匹配,匹配不成功(说明不需要进行缓存)则不进行任何操作直接返回vnode,vnode是一个VNode类型的对象,不了解VNode的同学可以参考笔者的另一篇文章 《VNode节点》 .

检测include与exclude属性匹配的函数很简单,include与exclude属性支持字符串如"a,b,c"这样组件名以逗号隔开的情况以及正则表达式。matches通过这两种方式分别检测是否匹配当前组件。

接下来的事情很简单,根据key在this.cache中查找,如果存在则说明之前已经缓存过了,直接将缓存的vnode的componentInstance(组件实例)覆盖到目前的vnode上面。否则将vnode存储在cache中。

最后返回vnode(有缓存时该vnode的componentInstance已经被替换成缓存中的了)。

watch

用watch来监听include与exclude这两个属性的改变,在改变的时候修改cache缓存中的缓存数据。

来看一下pruneCache的实现。

遍历cache中的所有项,如果不符合filter指定的规则的话,则会执行pruneCacheEntry。pruneCacheEntry则会调用组件实例的$destroy方法来将组件销毁。

Vue.js内部将DOM节点抽象成了一个个的 VNode节点 , keep-alive组件的缓存也是基于VNode节点的而不是直接存储DOM结构。它将满足条件(include与exclude)的组件在cache对象中缓存起来,在需要重新渲染的时候再将vnode节点从cache对象中取出并渲染。

原文: 聊聊keep-alive组件的使用及其实现原理

Vue keep-alive防止重复渲染DOM总结

一,VUE单页面应用文件实现返回上一页面时保留之前的数据

最近在做项目时,需要实现下面场景:

在页面查询列表,进入详情页时,返回时需要页面返回到上次浏览的位置(保留之前的当前页和搜索条件数据)

针对上面的 需求:
页面的缓存,我们需要用到vue的内置组件 keep-alive ,来缓存列表页面,同时配合路由选项俩更改页面的数据
1.在路由出口渲染组件时配置:

介绍一下 <keep-alive> 这个内置组件
<keep-alive>是vue 的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。
<keep-alive> 包裹动态组件时,而不是销毁他们。和 <transition> 相似, <keep-alive> 是一个抽象组件:他自身不会渲染一个DOM元素,也不会出现在父组件链中。
<keep-alive> 有两个属性:
(1) include :字符串或者正则表达式,只有匹配的组件会被缓存。
exclude :字符串或者正则表达式,任何匹配的组件都不会被缓存。
2.在需要做缓存的页面加上name

注意需要缓存页面里的name里的名字 要和 include里的名字一致才会缓存。

Vue keep-alive防止重复渲染DOM总结

一,VUE单页面应用文件实现返回上一页面时保留之前的数据

最近在做项目时,需要实现下面场景:

在页面查询列表,进入详情页时,返回时需要页面返回到上次浏览的位置(保留之前的当前页和搜索条件数据)

针对上面的 需求:
页面的缓存,我们需要用到vue的内置组件 keep-alive ,来缓存列表页面,同时配合路由选项俩更改页面的数据
1.在路由出口渲染组件时配置:

介绍一下 <keep-alive> 这个内置组件
<keep-alive>是vue 的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。
<keep-alive> 包裹动态组件时,而不是销毁他们。和 <transition> 相似, <keep-alive> 是一个抽象组件:他自身不会渲染一个DOM元素,也不会出现在父组件链中。
<keep-alive> 有两个属性:
(1) include :字符串或者正则表达式,只有匹配的组件会被缓存。
exclude :字符串或者正则表达式,任何匹配的组件都不会被缓存。
2.在需要做缓存的页面加上name

注意需要缓存页面里的name里的名字 要和 include里的名字一致才会缓存。

vue开启keep-alive需要注意的问题

一、开启keep-alive

在这里keep-alive配合了router-view使用,keep-alive本身是vue2.0的功能,并不是vue-router的,所以在vue1.0版本是不支持的。

二、产生的问题

keep-alive能使组件数据缓存,因此。如果有一个新闻列表,点击进入查看详情,返回点击查看其他新闻详情这时发现数据并没有更新,造成了数据不刷新的情况。

因此,我试了以下网友提出的解决方法,发现并没有什么用(或许是我弄错了)。

三、我的解决方法

因此,个人拙见,我是这么解决的。在详情组件里监听路由变化再次赋值给ID,通过activated钩子触发请求函数,这时返回详情页面再次进入发现原有的数据还在,但是过几秒后数据就刷新了,数据是刷新了但是体验是非常不好的。因此需要用到另一个钩子deactivated销毁,离开详情页面时(deactivated)通过小技巧把当前的内容隐藏,再次进入详情页面时(activated)就不会看到原来的内容了,然后ajax请求数据完成后把它显示出来即可。

当引入keep-alive的时候,页面第一次进入,钩子的触发顺序created-> mounted-> activated,退出时触发deactivated。当再次进入(前进或者后退)时,只触发activated。

四、2019新发现

使用exclude属性不缓存模板组件即可,没有上面那么复杂了。

vue 缓存组件keep-alive

kee-alive 是 Vue 内置的一个组件, 可以使被包含的组件保留状态,或避免重新渲染 。也就是所谓的组件缓存

keep-alive是一个抽象的组件,缓存的组件不会被mounted,为此提供activated和deactivated钩子函数

在2.1.0 版本后keep-alive新加入了两个属性: include(包含的组件缓存生效) 与 exclude(排除的组件不缓存,优先级大于include) 。

keep-alive可以接收3个属性做为参数进行匹配对应的组件进行缓存:

include 包含的组件(可以为字符串,数组,以及正则表达式,只有匹配的组件会被缓存)

exclude 排除的组件(以为字符串,数组,以及正则表达式,任何匹配的组件都不会被缓存)

max 缓存组件的最大值(类型为字符或者数字,可以控制缓存组件的个数)

配合router使用

1.keep-alive 先匹配被包含组件的 name 字段,如果 name 不可用,则匹配当前组件 components 配置中的注册名称。

2.keep-alive 不会在函数式组件中正常工作,因为它们没有缓存实例。

3.当匹配条件同时在 include 与 exclude 存在时,以 exclude 优先级最高(当前vue 2.4.2 version)。比如:包含于排除同时匹配到了组件A,那组件A不会被缓存。

4.包含在 keep-alive 中,但符合 exclude ,不会调用activated和 deactivated。

参考 https://juejin.cn/post/6844903918313406472

参考 https://www.imooc.com/article/302879

乐玩宠还为您提供以下相关内容希望对您有帮助:

vue使用keep-alive实现页面前进刷新,后退缓存

vue中,我们有时候需要实现这种场景:1.搜索页面到列表页面,需要刷新重新获取数据。2.从详情页面返回列表页面需要记住上次浏览的状态。具体流程如下:第一步:在路由配置文件中为列表页设置meta参数,里面包含useCatch和keepAlive ...

vue 缓存组件keep-alive

配合router使用 1.keep-alive 先匹配被包含组件的 name 字段,如果 name 不可用,则匹配当前组件 components 配置中的注册名称。 2.keep-alive 不会在函数式组件中正常工作,因为它们没有缓存实例。 3.当匹配条件同时...

vue开启keep-alive需要注意的问题

一、开启keep-alive 在这里keep-alive配合了router-view使用,keep-alive本身是vue2.0的功能,并不是vue-router的,所以在vue1.0版本是不支持的。二、产生的问题 keep-alive能使组件数据缓存,因此。如果有一个新闻列表,...

vue 路由缓存

使用的时候可以在根组件中通过$route.meta.keepAlive取到该值,然后进行v-if判断即可,如图 2,这样使用起来相对灵活一点。使用keep-alive缓存路由后,已经解决了主要问题,但是有新的问题出现。缓存过的组件重 新被激活时不...

Vue keep-alive防止重复渲染DOM总结

针对上面的 需求: 页面的缓存,我们需要用到vue的内置组件 keep-alive ,来缓存列表页面,同时配合路由选项俩更改页面的数据 1.在路由出口渲染组件时配置:介绍一下 &lt;keep-alive&gt; 这个内置组件 &lt;keep-alive&gt;是vue...

Vue 怎么缓存当前的组件?缓存后怎么更新?说说你对keep-alive的...

使用 &lt;keep-alive&gt; keep-alive 是 vue 中内置的一个组件 源码位置:src/core/components/keep-alive.js 可以看到该组件没有 template ,而是用了 render ,在组件渲染的时候会自动执行 render 函数 this.cache 是一个对象...

vue的keep-alive组件的使用及其实现原理

keep-alive提供了两个生命钩子,分别是activated与deactivated。因为keep-alive会将组件保存在内存中,并不会销毁以及重新创建,所以不会重新调用组件的created等方法,需要用activated与deactivated这两个生命钩子来得知当前组件是否...

...页面时的位置,无论用什么方法,是必须要用keep-alive吗?

3.组合使用 这两个我感觉很配,当我们使用keep-alive缓存了页面组件,我们需要在A面来触发B页面的列表刷新或其他方法时,这时候使用EventBus就非常方便,其他方法也可以,比如说使用vuex,但是此时就没有直接使用EventBus方便...

vue使用keep-alive缓存页面,返回页面时刷新部分数据

1、不使用keep-alive的情况:beforeRouteEnter --&gt; created --&gt; mounted --&gt; destroyed 2、使用keep-alive的情况:beforeRouteEnter --&gt; created --&gt; mounted --&gt; activated --&gt; deactivated 3、使用keep-alive,并且...

vue页面缓存(keepAlive)

同人博客搬迁~~~(播客主页: https://www.cnblogs.com/epines/ )页面缓存在页面中长期会使用到,可以更快速的在页面切换期间的资源获取 主要是用keep-alive实现 在vue项目中,相关的写法比较多,还有一些注意点需要仔细 ...

Top
8.558522s